2016-12-14 40 views
2

我期望一个完全屏蔽的数组的求和结果为零,但会返回“被屏蔽”的结果。我怎样才能让函数返回零?Numpy masked_array sum

>>> a = np.asarray([1, 2, 3, 4]) 
>>> b = np.ma.masked_array(a, mask=~(a > 2)) 
>>> b 
masked_array(data = [-- -- 3 4], 
      mask = [ True True False False], 
     fill_value = 999999) 

>>> b.sum() 
7 
>>> b = np.ma.masked_array(a, mask=~(a > 5)) 
>>> b 
masked_array(data = [-- -- -- --], 
     mask = [ True True True True], 
    fill_value = 999999) 


>>> b.sum() 
masked 
>>> np.ma.sum(b) 
masked 
>>> 

这里还有一个意想不到的事情:

>>> b.sum() + 3 
masked 

回答

1

在你最后一种情况:

In [197]: bs=b1.sum() 
In [198]: bs.data 
Out[198]: array(0.0) 
In [199]: bs.mask 
Out[199]: array(True, dtype=bool) 
In [200]: repr(bs) 
Out[200]: 'masked' 
In [201]: str(bs) 
Out[201]: '--' 

如果我指定keepdims,我得到一个不同的数组:

In [208]: bs=b1.sum(keepdims=True) 
In [209]: bs 
Out[209]: 
masked_array(data = [--], 
      mask = [ True], 
     fill_value = 999999) 
In [210]: bs.data 
Out[210]: array([0]) 
In [211]: bs.mask 
Out[211]: array([ True], dtype=bool) 

这里的相关的在sum代码的蚂蚁部分:

def sum(self, axis=None, dtype=None, out=None, keepdims=np._NoValue): 
    kwargs = {} if keepdims is np._NoValue else {'keepdims': keepdims} 

    _mask = self._mask 
    newmask = _check_mask_axis(_mask, axis, **kwargs) 
    # No explicit output 
    if out is None: 
     result = self.filled(0).sum(axis, dtype=dtype, **kwargs) 
     rndim = getattr(result, 'ndim', 0) 
     if rndim: 
      result = result.view(type(self)) 
      result.__setmask__(newmask) 
     elif newmask: 
      result = masked 
     return result 
    .... 

这是产生在你的情况masked

newmask = np.ma.core._check_mask_axis(b1.mask, axis=None) 
... 
elif newmask: result = masked 

线。 newmask在所有值都被屏蔽的情况下为真,而False则不是。返回np.ma.masked的选择是故意的。

计算的核心是:

In [218]: b1.filled(0).sum() 
Out[218]: 0 

的代码的其余部分决定是否返回一个标量或掩蔽的阵列。

============

而且为你增加:

In [232]: np.ma.masked+3 
Out[232]: masked 

它看起来像np.ma.masked是传播本身横跨计算一个特殊的数组。有点像np.nan

+0

我预计要返回一个标值,而不是一个数组(它已经结束了,我找所有尺寸的总和)。 – orange

+1

我加了'sum'代码的相关部分。我可以理解,为什么当输入被完全屏蔽时,返回值可能会有一些不明确的地方。关于这是否正确,我不知道任何辩论。如果你不喜欢这个结果,你可以将总和应用于'b.filled(0)'。 – hpaulj

+0

看起来像推理是'如果所有值都被屏蔽了,它就不能给出正确的标量值(即使总和的起始值为0)'。 – hpaulj