为什么我的数组在 Numpy 中进行多维索引后会丢失其掩码?
Why does my array lose its mask after doing multidimensional indexing in Numpy?
我希望使用多维 MaskedArray 作为索引数组:
数据:
In [149]: np.ma.arange(10, 60, 2)
Out[149]:
masked_array(data = [10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58],
mask = False,
fill_value = 999999)
指数:
In [140]: np.ma.array(np.arange(20).reshape(4, 5),
mask=np.arange(20).reshape(4, 5) % 3)
Out[140]:
masked_array(data =
[[0 -- -- 3 --]
[-- 6 -- -- 9]
[-- -- 12 -- --]
[15 -- -- 18 --]],
mask =
[[False True True False True]
[ True False True True False]
[ True True False True True]
[False True True False True]],
fill_value = 999999)
期望的输出:
In [151]: np.ma.arange(10, 60, 2)[np.ma.array(np.arange(20).reshape(4, 5), mask=np.arange(20).reshape(4, 5) % 3)]
Out[151]:
masked_array(data =
[[10 -- -- 16 --]
[-- 22 -- -- 28]
[-- -- 34 -- --]
[40 -- -- 46 --]],
mask =
False,
fill_value = 999999)
实际输出:
In [160]: np.ma.arange(10, 60, 2)[np.ma.array(np.arange(20).reshape(4, 5), mask=np.arange(20).reshape(4, 5) % 3)]
Out[160]:
masked_array(data =
[[10 12 14 16 18]
[20 22 24 26 28]
[30 32 34 36 38]
[40 42 44 46 48]],
mask =
False,
fill_value = 999999)
为什么生成的数组丢失了掩码?根据此处的回答:Indexing with Masked Arrays in numpy,这种索引方法非常糟糕。为什么?
尝试使用这样的 choose 方法:
np.ma.array(np.arange(20).reshape(4, 5), mask=np.arange(20).reshape(4, 5) % 3).
choose(np.ma.arange(10, 60, 2))
给出:
masked_array(data =
[[10 -- -- 16 --]
[-- 22 -- -- 28]
[-- -- 34 -- --]
[40 -- -- 46 --]],
mask =
[[False True True False True]
[ True False True True False]
[ True True False True True]
[False True True False True]],
fill_value = 999999)
看起来使用掩码数组进行索引只是忽略了掩码。在不深入研究文档或代码的情况下,我会说 numpy
数组索引没有掩码数组 subclass 的特殊知识。您得到的数组只是正常的 arange(20)
索引。
但是你可以执行正常的索引,'copy'掩码:
In [13]: data=np.arange(10,60,2)
In [14]: mI = np.ma.array(np.arange(20).reshape(4,5),mask=np.arange(20).reshape(4,5) % 3)
...
In [16]: np.ma.array(data[mI], mask=mI.mask)
Out[16]:
masked_array(data =
[[10 -- -- 16 --]
[-- 22 -- -- 28]
[-- -- 34 -- --]
[40 -- -- 46 --]],
mask =
[[False True True False True]
[ True False True True False]
[ True True False True True]
[False True True False True]],
fill_value = 999999)
你真的需要将索引和屏蔽合并到一个操作中吗(和屏蔽数组)。如果掩码是分开的,此操作同样有效。
I = np.arange(20).reshape(4,5)
m = (np.arange(20).reshape(4,5) % 3)>0
np.ma.array(data[I], mask=m)
如果屏蔽的索引元素无效(例如超出范围),您可以用有效的内容填充它们(如果需要,随后进行屏蔽):
data[mI.filled(fill_value=0)]
您是否在 numpy 掩码数组文档中看到过使用掩码数组索引另一个数组的示例?或者所有的屏蔽数组都是'data'?设计者可能从未打算让您使用屏蔽索引。
掩码数组 .choose
之所以有效,是因为它使用了一种已针对掩码数组进行 subclass 处理的方法。常规索引可能会将索引转换为常规数组,例如:data[np.asarray(mI)]
.
MaskedArray
class 的 __getitem__
方法开始:
def __getitem__(self, indx):
Return the item described by i, as a masked array.
"""
# This test is useful, but we should keep things light...
# if getmask(indx) is not nomask:
# msg = "Masked arrays must be filled before they can be used as indices!"
# raise IndexError(msg)
这是在掩码数组上执行 []
时调用的方法。显然,开发人员考虑正式阻止使用屏蔽索引,但认为这不是一个足够重要的问题。有关详细信息,请参阅 np.ma.core.py
文件。
我希望使用多维 MaskedArray 作为索引数组:
数据:
In [149]: np.ma.arange(10, 60, 2)
Out[149]:
masked_array(data = [10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58],
mask = False,
fill_value = 999999)
指数:
In [140]: np.ma.array(np.arange(20).reshape(4, 5),
mask=np.arange(20).reshape(4, 5) % 3)
Out[140]:
masked_array(data =
[[0 -- -- 3 --]
[-- 6 -- -- 9]
[-- -- 12 -- --]
[15 -- -- 18 --]],
mask =
[[False True True False True]
[ True False True True False]
[ True True False True True]
[False True True False True]],
fill_value = 999999)
期望的输出:
In [151]: np.ma.arange(10, 60, 2)[np.ma.array(np.arange(20).reshape(4, 5), mask=np.arange(20).reshape(4, 5) % 3)]
Out[151]:
masked_array(data =
[[10 -- -- 16 --]
[-- 22 -- -- 28]
[-- -- 34 -- --]
[40 -- -- 46 --]],
mask =
False,
fill_value = 999999)
实际输出:
In [160]: np.ma.arange(10, 60, 2)[np.ma.array(np.arange(20).reshape(4, 5), mask=np.arange(20).reshape(4, 5) % 3)]
Out[160]:
masked_array(data =
[[10 12 14 16 18]
[20 22 24 26 28]
[30 32 34 36 38]
[40 42 44 46 48]],
mask =
False,
fill_value = 999999)
为什么生成的数组丢失了掩码?根据此处的回答:Indexing with Masked Arrays in numpy,这种索引方法非常糟糕。为什么?
尝试使用这样的 choose 方法:
np.ma.array(np.arange(20).reshape(4, 5), mask=np.arange(20).reshape(4, 5) % 3).
choose(np.ma.arange(10, 60, 2))
给出:
masked_array(data =
[[10 -- -- 16 --]
[-- 22 -- -- 28]
[-- -- 34 -- --]
[40 -- -- 46 --]],
mask =
[[False True True False True]
[ True False True True False]
[ True True False True True]
[False True True False True]],
fill_value = 999999)
看起来使用掩码数组进行索引只是忽略了掩码。在不深入研究文档或代码的情况下,我会说 numpy
数组索引没有掩码数组 subclass 的特殊知识。您得到的数组只是正常的 arange(20)
索引。
但是你可以执行正常的索引,'copy'掩码:
In [13]: data=np.arange(10,60,2)
In [14]: mI = np.ma.array(np.arange(20).reshape(4,5),mask=np.arange(20).reshape(4,5) % 3)
...
In [16]: np.ma.array(data[mI], mask=mI.mask)
Out[16]:
masked_array(data =
[[10 -- -- 16 --]
[-- 22 -- -- 28]
[-- -- 34 -- --]
[40 -- -- 46 --]],
mask =
[[False True True False True]
[ True False True True False]
[ True True False True True]
[False True True False True]],
fill_value = 999999)
你真的需要将索引和屏蔽合并到一个操作中吗(和屏蔽数组)。如果掩码是分开的,此操作同样有效。
I = np.arange(20).reshape(4,5)
m = (np.arange(20).reshape(4,5) % 3)>0
np.ma.array(data[I], mask=m)
如果屏蔽的索引元素无效(例如超出范围),您可以用有效的内容填充它们(如果需要,随后进行屏蔽):
data[mI.filled(fill_value=0)]
您是否在 numpy 掩码数组文档中看到过使用掩码数组索引另一个数组的示例?或者所有的屏蔽数组都是'data'?设计者可能从未打算让您使用屏蔽索引。
掩码数组 .choose
之所以有效,是因为它使用了一种已针对掩码数组进行 subclass 处理的方法。常规索引可能会将索引转换为常规数组,例如:data[np.asarray(mI)]
.
MaskedArray
class 的 __getitem__
方法开始:
def __getitem__(self, indx):
Return the item described by i, as a masked array.
"""
# This test is useful, but we should keep things light...
# if getmask(indx) is not nomask:
# msg = "Masked arrays must be filled before they can be used as indices!"
# raise IndexError(msg)
这是在掩码数组上执行 []
时调用的方法。显然,开发人员考虑正式阻止使用屏蔽索引,但认为这不是一个足够重要的问题。有关详细信息,请参阅 np.ma.core.py
文件。