numpy MaskedConstant 布尔转换不一致

0 投票
1 回答
2544 浏览
提问于 2025-04-18 15:08

在Numpy Python 1.8.0版本中:

当我们在处理带有掩码的数组时,使用一些聚合函数(比如最小值和最大值)可能会遇到麻烦,因为结果有可能是一个叫做MaskedConstant的东西。这种情况会变得更加复杂,尤其是出现了一些奇怪的行为。

import numpy
testC = numpy.ma.masked_array([1,2],[True,True]).min()
print type(testC) # -> <class 'numpy.ma.core.MaskedConstant'> 
print bool((testC==None)) # -> False 
print bool((testC!=None)) # -> False (???) 

我不太想用isinstance这样的方式来判断,因为我觉得这样会让代码和这种内部类型紧密关联。我可以通过小心地测试不等于(!=)来让测试通过,这样任何其他有效的数字都应该能通过。但我觉得这样做有风险,因为如果逻辑反转过来,按照这种行为就不一定正确了。

我正在尝试安全地计算多个不同的带掩码数组的最小值。我不能一次性加载所有的数组,而是需要将部分聚合的结果结合起来。在这个组合的过程中,我遇到了这个问题。

1 个回答

0

在你的代码中,numpy.ma.masked_array([1,2], [True,True]).min() 返回的值是 masked(也就是 numpy.ma.masked,它是 numpy.ma.core.MaskedConstant 的一个实例)。这表示在尝试找出一个实际上是空的集合的最小值时,numpy 的掩码数组代码是这样处理的。你可以把它和普通的 numpy 数组的表现进行对比:

In [36]: np.array([]).min()
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-33-a63f9cff1d67> in <module>()
----> 1 np.array([]).min()
...<snip>...

ValueError: zero-size array to reduction operation minimum which has no identity

MaskedConstant 类的 __eq__ 方法会返回 masked,如果这个实例(也就是 self)本身是 masked,不管其他的参数是什么。换句话说,masked == <其他任何东西> 也会返回 masked。举个例子:

In [28]: from numpy.ma import masked

In [29]: type(masked)
Out[29]: numpy.ma.core.MaskedConstant

In [30]: masked == 99
Out[30]: masked

In [31]: masked == [1, 2, 3]
Out[31]: masked

In [32]: masked == masked
Out[32]: masked

要测试这个值,你可以使用 is

In [33]: masked is masked
Out[33]: True

In [34]: masked is 99
Out[34]: False

In [35]: masked is None
Out[35]: False

在你的代码中,你可以用 testC is masked 来测试 min 方法的返回值。当这种情况发生时,意味着这一批中的所有值都是被掩盖的,所以这一批对你所有掩盖数组的聚合最小值没有影响。

撰写回答