Python numpy掩码数组初始化

6

在我的工作中,我经常使用掩码数组,但是我遇到的一个问题是初始化掩码数组有点繁琐。具体而言,ma.zeros()ma.empty()返回的掩码数组的 掩码与数组维度不匹配。 我需要这样做的原因是,如果我不给数组的特定元素赋值,它将默认为掩码状态。

In [4]: A=ma.zeros((3,))
...
masked_array(data = [ 0.  0.  0.],
             mask = False,
       fill_value = 1e+20)

我可以随后分配这个掩码:
In [6]: A.mask=ones((3,))
...
masked_array(data = [-- -- --],
             mask = [ True  True  True],
       fill_value = 1e+20)

但是为什么我要使用两行代码来初始化数组呢?相反,我可以忽略ma.zeros()的功能,在一行中指定掩码和数据:

In [8]: A=ma.masked_array(zeros((3,)),mask=ones((3,)))
...
masked_array(data = [-- -- --],
             mask = [ True  True  True],
       fill_value = 1e+20)

但我认为这也很笨重。我已经仔细查看了numpy.ma文档,但我找不到一个简洁的方法来处理这个问题。我有没有错过什么明显的东西?

2个回答

5
好的,ma.zeros 中的掩码实际上是一个特殊常量 ma.nomask,它对应于 np.bool_(False)。它只是一个占位符,告诉 NumPy 掩码还没有被设置。使用 nomask 实际上会显著加速 np.ma:如果我们预先知道没有掩码值,就不需要跟踪掩码值的位置。

最好的方法是如果不需要设置掩码,则不要明确设置掩码,让 np.ma 在需要时设置(例如,当您试图对负数取对数时)。


附注1:要将掩码设置为与输入相同形状的 False 数组,请使用:

np.ma.array(..., mask=False)

这更容易输入。请注意,这实际上是Python的False而不是np.ma.nomask... 同样地,使用mask=True强制所有输入都被屏蔽(即,mask将是一个bool ndarray,其中每个值都为True,与data具有相同的形状)。


附注2: 如果您需要在初始化后设置掩码,则不应该使用分配给.mask,而应该分配给特殊值np.ma.masked,这样更安全:

a[:] = np.ma.masked

嗨,Pierre,感谢您的回复。在我的应用程序中,我总是希望有一个掩码,以便如果我最终没有分配给索引,则默认情况下仍然被掩码覆盖(我已编辑我的问题以更好地反映这一点)。您的“旁注”似乎正是我一直在寻找的! - Thom Chubb

0

很遗憾,你的第二个侧注建议对于一个具有多个维度的数组是不适用的:

a = ma.zeros( (2,2) )
a[0][0] = ma.masked
a
masked_array(data =
 [[ 0.  0.]
 [ 0.  0.]],
         mask =
 False,
   fill_value = 1e+20)

和 OP 一样,我也没有找到一个简洁的方法来解决这个问题。掩码整行将正确初始化掩码:

 a[0] = ma.masked
 a
 masked_array(data =
 [[-- --]
 [0.0 0.0]],
             mask =
 [[ True  True]
 [False False]],
       fill_value = 1e+20)

但如果这不是你想做的事情,那么你就需要执行a[0] = ma.nomask来撤销它。在a = ma.zeros((2,2))之后立即执行a[0] = ma.nomask是没有任何效果的。


我不确定这里到底发生了什么,但答案可能在“基本”和“高级”索引之间的差异中: http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html1)如果您分配a [0,0] = ma.masked,您会发现它按预期工作。2)如果您以您所做的方式分配值(例如a [0] [0] = 1.),则它会按预期工作。我不确定为什么在分配特殊值和浮点数之间的行为会有所不同。 - Thom Chubb

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