【问题标题】:Why does np.ma.array take an inverted mask?为什么 np.ma.array 采用倒置掩码?
【发布时间】:2020-09-15 19:02:46
【问题描述】:

我有一些数组

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 解释一下这种设计选择。

【问题讨论】:

  • 你的掩码是一个整数数组,而不是布尔值
  • @yatu 谢谢,已修复。随意编辑不准确之处:)我希望问题本身很清楚。
  • 有趣的问题,但我觉得这就是掩码数组的定义。 "Masked values of True exclude the corresponding element from any computation."。也许this answer 解决了它?
  • 您是在问为什么代码会以它的方式工作(考虑到它是如何记录的),还是为什么开发人员选择了这个特定的约定(与您的直觉认为的相反)?
  • @hpauli 我实际上不明白你所说的不同。我问为什么 np.ma 使用与 np 不同的约定。我的直觉是它们应该是一样的,我不介意哪种方式。

标签: python numpy masked-array


【解决方案1】:
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 并谈论“屏蔽”,但我们真正在做的是“选择”。 a[idx] 操作返回 a 的元素,其中 idx 为 True。这与使用 nonzero 元组索引相同:

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

np.ma 中,掩码用于'掩码'的意义,覆盖。

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 返回一个数组,其中 '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])

【讨论】:

  • 感谢您的回复!我问为什么 np 和 np.ma 的标准不同,我理解你在这里指定的差异。
  • 我调用数组来访问数据数组并不重要,我希望它的行为相同,但事实并非如此。我看到文档指定了行为,并且我理解行为。我不明白导致选择表示“不选择什么”的掩码的逻辑,而不是“选择什么”的 numpy 标准
  • 我试图解释的是布尔数组的两种用途是不相关的。选择和屏蔽是不同的任务,不必遵循相同的逻辑。
  • 好吧,有没有不应用np.logical_not~ 从已经存在的(反转)掩码中获取掩码数组的有效方法?不先遍历整个掩码进行否定?
  • 你为什么害怕一个简单的~?如果你追求效率,不要使用np.ma;这是一门便利课,而不是表演课。我认为它没有任何自定义 c 代码;都是 Python。
猜你喜欢
  • 2011-08-01
  • 1970-01-01
  • 2020-01-14
  • 2019-09-23
  • 2017-10-16
  • 1970-01-01
  • 2012-05-16
  • 2018-08-14
相关资源
最近更新 更多