0

我偶然发现了一个关于屏蔽无符号整数数组和np.ma.argmax.

考虑以下数组:

>>> marr = np.ma.array(np.array([[2,2,2], [3,3,3], [1,1,1]]), mask=False, dtype=np.uint16)
>>> marr
masked_array(data =
 [[2 2 2]
 [3 3 3]
 [1 1 1]],
             mask =
 [[False False False]
 [False False False]
 [False False False]],
       fill_value = 999999)

如果我使用np.ma.argmax结果是我所期望的:

>>> print(np.ma.argmax(marr, axis=0))
[1 1 1]

如果我现在屏蔽最后一行,结果是错误的:

>>> marr.mask[2] = True
>>> marr
masked_array(data =
 [[2 2 2]
 [3 3 3]
 [-- -- --]],
             mask =
 [[False False False]
 [False False False]
 [ True  True  True]],
       fill_value = 999999)
>>> print(np.ma.argmax(marr, axis=0))
[2 2 2]   # why?

它现在认为被屏蔽的行是最大值?我什至将其更改fill_value为 0,但结果保持不变:它仍然认为被屏蔽的行是最大值。似乎这只影响无符号整数数组。

但是np.ma.MaskedArray.argmaxnp.argmax返回正确的结果:

>>> print(marr.argmax(axis=0))
[1 1 1]
>>> print(np.argmax(marr, axis=0))
[1 1 1]

为什么np.ma.argmax这里没有做正确的事情?据我所知,它被定义为方法本身

4

2 回答 2

1

这是np.ma.argmax(通过ipython ??魔术)(版本'1.11.0')的代码

Definition:  np.ma.argmax(a, axis=None, fill_value=None)
Source:
def argmax(a, axis=None, fill_value=None):
    "Function version of the eponymous method."
    if fill_value is None:
        fill_value = default_fill_value(a)
        try:
            fill_value = -fill_value
        except:
            pass
    d = filled(a, fill_value)
    return d.argmax(axis=axis)

对于方法:

def argmax(self, axis=None, fill_value=None, out=None):
    if fill_value is None:
        fill_value = maximum_fill_value(self._data)
    d = self.filled(fill_value).view(ndarray)
    return d.argmax(axis, out=out)

该函数使用不同的填充值

In [180]: np.ma.maximum_fill_value(marr)
Out[180]: 0

In [181]: np.ma.maximum_fill_value(marr.astype(int))
Out[181]: -2147483648

In [182]: np.ma.default_fill_value(marr)
Out[182]: array(999999)

In [183]: -np.ma.default_fill_value(marr)
Out[183]: -999999

In [184]: np.ma.filled(marr,-np.ma.default_fill_value(marr))
Out[184]: 
array([[    2,     2,     2],
       [    3,     3,     3],
       [48577, 48577, 48577]], dtype=uint16)

In [186]: np.ma.filled(marr,np.ma.maximum_fill_value(marr))
Out[186]: 
array([[2, 2, 2],
       [3, 3, 3],
       [0, 0, 0]], dtype=uint16)

这是我的版本中的一个错误。2 月发生了变化,将argmax(和 argmin) 替换为 ( ) 方法argmax = _frommethod('argmax')

https://github.com/numpy/numpy/commit/36f76ea2e6e91062df12d3a46ccaed7822bc82f2

因此,该更正不在我的发行版中-大概不是您的。

所以现在坚持使用方法,或者提供你自己正确的填充值。

In [187]: np.ma.argmax(marr,axis=0,fill_value=0)
Out[187]: array([1, 1, 1], dtype=int32)
于 2016-06-11T15:46:48.050 回答
0

正如@hpaulj 已经暗示的那样,这是 numpy 版本 1.11.0 中的一个错误。在较新的 numpy 版本(例如 1.11.3)中,该错误已得到修复:

>>> import numpy as np
>>> np.__version__
'1.11.3'
>>> marr = np.ma.array(np.array([[2,2,2], [3,3,3], [1,1,1]]), mask=False, dtype=np.uint16)
>>> marr.mask[2] = True
>>> print(np.ma.argmax(marr, axis=0))
[1 1 1]
于 2017-01-17T00:51:13.227 回答