用Python整数列表和None值初始化numpy掩码数组

4

如在回答将具有None值的Python列表转换为带有nan值的numpy数组中所示,如果我们强制dtype=float,则可以轻松地从具有None值的列表初始化遮罩numpy数组。这些浮点值将被转换为nan,我们只需执行以下操作:

ma.masked_invalid(np.array(a, dtype=float), copy=False)

然而,对于像int这样的数据类型,这种方法是行不通的:

ma.masked_invalid(np.array(a, dtype=int), copy=False)

由于不存在 int nan,中间的 np.array 不会创建 None 值。

在基于 Python 整数列表初始化掩码数组并包含 None 值的情况下,最有效的方法是什么,以使这些 None 值成为遮罩?


我认为在没有一个对象数据类型的临时数组的情况下,很难找到一个好的解决方法。确保你选择的解决方案最终不会以对象数据类型结束。 - user2357112
3个回答

4
到目前为止,我发现最优雅的解决方案(尽管并不优雅)是初始化一个float类型的掩码数组,然后将其转换为int
ma.masked_invalid(np.array(a, dtype=float), copy=False).astype(int)

这会生成一个适当的NP数组,其中初始数组a中的None值被屏蔽。例如,对于:

a = [1, 2, 3, None, 4]
ma.masked_invalid(np.array(a, dtype=float), copy=False).astype(int)

我们得到:

masked_array(data = [1 2 3 -- 4],
             mask = [False False False  True False],
       fill_value = 999999)

此外,实际的掩码整数值变为最小整数,即。
ma.masked_invalid(np.array(column, dtype=float), copy=False).astype(int).data

提供:

array([                   1,                    2,                    3,
       -9223372036854775808,                    4])

0

是的,但最终我确实需要int类型。完整的答案应该为我提供一个int类型的掩码数组。最有效的方法是什么? - Andrzej Pronobis
似乎nan仍未转换为numpy int。那么通过对象的方式,最好的方法是什么? - Andrzej Pronobis

0

首先创建两个空数组,一个数据类型为int的数组将成为掩码ed数组,另一个数据类型为布尔型的数组将成为掩码本身。

然后遍历Python数组。在arr_without_none中,我们用默认值替换所有None的出现,并在mask_mat中存储Python数组中原始值是None还是整数。最后,我们从这两个组件生成一个掩码数组。

def masked_int_array(arr, default=0):
    arr_without_none = numpy.empty(len(arr), dtype=int)
    mask_mat = numpy.empty(len(arr), dtype=bool)
    for i in range(len(arr)):
        arr_without_none[i] = default if arr[i] is None else arr[i]
        mask_mat[i] = arr[i] is None
    return ma.array(data=arr_without_none, dtype=int, mask=mask_mat, copy=False)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接