将二维或一维掩码数组索引到 Numpy 中的一维数组的有效通用代码

问题描述

我想要二维或一维掩码数组的有效代码,以从中提取一维数组。在 2D 情况下,一列将被完全屏蔽并应删除(这可以按照 in this question for example 所示进行)。

import numpy as np

a = np.ma.masked_array(range(10*2),mask=[True,False]*10).reshape(10,2)
a = np.ma.masked_equal(a,13)
b = np.ma.masked_equal(np.array(range(10)),3)

print(a)
print(b)
# [[-- 1]
#  [-- 3]
#  [-- 5]
#  [-- 7]
#  [-- 9]
#  [-- 11]
#  [-- --]
#  [-- 15]
#  [-- 17]
#  [-- 19]]
# [0 1 2 -- 4 5 6 7 8 9]

# HERE I would like the same indexing valid for both (2D and 1D) situations:
a = a[:,~np.all(a.mask,axis=0)].squeeze()
b = b[:] # I am not supposed to kNow that b is actually 1D and not a problematic 2D array

print(a)
print(b)
# [1 3 5 7 9 11 -- 15 17 19]
# [0 1 2 -- 4 5 6 7 8 9]
print(a-b)
# [1 2 3 -- 5 6 -- 8 9 10]

什么是有效的 Pythonic 代码来实现这一目标?

子问题:令我惊讶的是,在我的尝试中,以下确实有效:

b = b[:,~np.all(b.mask,axis=0)].squeeze()
print(b)
# [1 3 5 7 9 11 -- 15 17 19]

为什么我对这个一维数组使用二维索引时没有收到 IndexError: too many indices for array 错误

有没有更好的选择来解决最初的问题?谢谢!

解决方法

您可以将 a = a[:,~np.all(a.mask,axis=0)].squeeze() 用于两种情况(一维和二维)。

在您示例的一维情况下,您会得到 b[:,~np.all(b.mask,axis=0)],即 b[:,True]。似乎这应该引发索引错误,但在这种情况下 True 的行为类似于 np.newaxis,即 b[:,True] 的结果是形状为 (10,1) 的数组。请参阅 this SO answer 了解为什么会这样以及其背后的动机是什么(答案与 0 维情况有关,但事实证明它同样适用于更高的维度)。 squeeze 然后删除这个额外的维度,以便您不会注意到它。