为什么 np.ma.array 采取倒置面具?

Why does np.ma.array take an inverted mask?

我有一些数组

a = np.array([1, 2, 3])

还有一些面具

mask = np.ones(a.shape, dtype=bool)

并且可以做到

np.testing.assert_almost_equal(a[mask], a)  # True

然而,

np.ma.array(a, mask)

等同于

a[np.logical_not(mask)]

np.ma.array(a, np.logical_not(mask))

等同于

a[mask]

这对我来说似乎违反直觉。

希望 numpy 对此设计选择做出解释。

In [6]: a = np.array([1,2,3])                                                            
In [7]: idx = np.array([1,0,1], bool)                                                    
In [8]: idx                                                                              
Out[8]: array([ True, False,  True])
In [9]: a[idx]                                                                           
Out[9]: array([1, 3])

仅仅因为您调用了一个布尔数组 mask,并不意味着它在任何意义上都表现得像 'mask'。我故意选择一个不同的名字。是的,我们确实经常称这样的数组为mask并谈论'masking',但我们真正做的是'selecting'。 a[idx] 操作 returns a 的元素,其中 idx 为 True。它与使用 nonzero 元组建立索引相同:

In [13]: np.nonzero(idx)                                                                 
Out[13]: (array([0, 2]),)

np.ma中掩码是在'mask out'的意义上使用的,覆盖。

In [10]: mm = np.ma.masked_array(a, mask=idx)                                            
In [11]: mm                                                                              
Out[11]: 
masked_array(data=[--, 2, --],
             mask=[ True, False,  True],
       fill_value=999999)
In [12]: mm.compressed()                                                                 
Out[12]: array([2])

在显示中,屏蔽值显示为“--”。正如 np.ma 文档所说,那些元素被认为是无效的,将被排除在计算之外。

mm.filled returns 一个数组,其中 'masked' 值替换为 'fill':

In [16]: mm.filled()                                                                     
Out[16]: array([999999,      2, 999999])

我们可以用 idx 做同样的事情:

In [17]: a[idx] = 999999                                                                 
In [18]: a                                                                               
Out[18]: array([999999,      2, 999999])