在 Numpy 中将 2D 或 1D 掩码数组索引到 1D 数组的有效通用代码

Valid generic code to index 2D or 1D masked arrays into 1D arrays in 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]

当我对这个 1D 数组使用 2D 索引时,为什么我没有收到 IndexError: too many indices for array 错误?

是否有更好的选择来解决原始问题?谢谢!

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

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