np.ma.argmax 无符号整数 dtype 的掩码数组 returns numpy 1.11.0 中的错误结果
np.ma.argmax on masked array of unsigned integer dtype returns wrong result in numpy 1.11.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.argmax
and np.argmax
return正确结果:
>>> print(marr.argmax(axis=0))
[1 1 1]
>>> print(np.argmax(marr, axis=0))
[1 1 1]
为什么 np.ma.argmax
在这里没有做正确的事情?据我所知,它被定义为 the method itself.
这是 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
所以那个更正不在我的发行版中 - 大概不是你的。
所以现在坚持使用方法,或者提供您自己的正确方法 fill_value。
In [187]: np.ma.argmax(marr,axis=0,fill_value=0)
Out[187]: array([1, 1, 1], dtype=int32)
正如@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]
我偶然发现了一个关于屏蔽无符号整数数组和 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.argmax
and np.argmax
return正确结果:
>>> print(marr.argmax(axis=0))
[1 1 1]
>>> print(np.argmax(marr, axis=0))
[1 1 1]
为什么 np.ma.argmax
在这里没有做正确的事情?据我所知,它被定义为 the method itself.
这是 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
所以那个更正不在我的发行版中 - 大概不是你的。
所以现在坚持使用方法,或者提供您自己的正确方法 fill_value。
In [187]: np.ma.argmax(marr,axis=0,fill_value=0)
Out[187]: array([1, 1, 1], dtype=int32)
正如@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]