为什么我的数组在Numpy中进行多维索引后会丢失它的掩码?

时间:2015-06-01 23:23:03

标签: python numpy multidimensional-array indexing

我希望使用多维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,这种索引方法非常糟糕。为什么呢?

2 个答案:

答案 0 :(得分:3)

看起来像使用蒙版数组进行索引只是忽略了掩码。如果不深入研究文档或代码,我会说numpy数组索引对掩码数组子类没有特别的了解。您获得的数组只是正常的arange(20)索引。

但是你可以执行正常的索引编制,然后复制'面具:

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蒙面数组docs中看到使用蒙面数组索引另一个数组的例子?或者是所有蒙面数组'数据'?设计师可能从未打算让您使用屏蔽索引。

屏蔽数组.choose有效,因为它使用的方法已经为掩码数组进行了子类化。常规索引可能会将索引转换为常规数组,例如:data[np.asarray(mI)]

__getitem__类的MaskedArray方法开始:

    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文件。

答案 1 :(得分:0)

尝试使用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)