通过布尔掩码数组选择numpy数组的元素

Posted

技术标签:

【中文标题】通过布尔掩码数组选择numpy数组的元素【英文标题】:Select elements of numpy array via boolean mask array 【发布时间】:2013-11-27 20:15:28 【问题描述】:

我有一个长度为n 的布尔掩码数组a

a = np.array([True, True, True, False, False])

我有一个包含n 列的二维数组:

b = np.array([[1,2,3,4,5], [1,2,3,4,5]])

我想要一个只包含“真”值的新数组,例如

c = ([[1,2,3], [1,2,3]])

c = a * b 不起作用,因为它还包含我不想要的虚假列的“0”

c = np.delete(b, a, 1) does not work

有什么建议吗?

【问题讨论】:

【参考方案1】:

你可能想要这样的东西:

>>> a = np.array([True, True, True, False, False])
>>> b = np.array([[1,2,3,4,5], [1,2,3,4,5]])
>>> b[:,a]
array([[1, 2, 3],
       [1, 2, 3]])

请注意,要使这种索引正常工作,它必须是 ndarray,就像您使用的那样,而不是 list,否则它会将 FalseTrue 解释为 01 并给你这些专栏:

>>> b[:,[True, True, True, False, False]]   
array([[2, 2, 2, 1, 1],
       [2, 2, 2, 1, 1]])

【讨论】:

我用过这个解决方案,效果很好!但是在扩大到形状为(2800000,600)ndarray 时,尝试使用具有200 True 值的掩码会很慢。有什么优化吗? 280 万?通常我会建议及时编译 - numba.pydata.org - 实际上不确定它会在这里有所帮助。 尝试numpy.compress(用于布尔值)或numpy.take(用于索引),请参阅***.com/q/46041811/882436 我确实计算了掩码,并且必须将掩码转换为类型 np.bool。所以我加了b[:,a.astype(np.bool)]【参考方案2】:

您可以使用numpy.ma 模块并使用np.ma.masked_array 函数来执行此操作。

>>> x = np.array([1, 2, 3, -1, 5])                                                
>>> mx = ma.masked_array(x, mask=[0, 0, 0, 1, 0])
masked_array(data=[1, 2, 3, --, 5], mask=[False, False,  False, True, False], fill_value=999999)

【讨论】:

【参考方案3】:

希望我不会太迟!这是你的数组:

X = np.array([[1, 2, 3, 4, 5], 
              [1, 2, 3, 4, 5]])

让我们创建一个与X 形状相同的零数组:

mask = np.zeros_like(X)
# array([[0, 0, 0, 0, 0],
#        [0, 0, 0, 0, 0]])

然后,使用1 指定要屏蔽或隐藏的列。在这种情况下,我们希望将最后 2 列屏蔽掉。

mask[:, -2:] = 1
# array([[0, 0, 0, 1, 1],
#        [0, 0, 0, 1, 1]])

创建一个掩码数组:

X_masked = np.ma.masked_array(X, mask)
# masked_array(data=[[1, 2, 3, --, --],
#                    [1, 2, 3, --, --]],
#              mask=[[False, False, False,  True,  True],
#                    [False, False, False,  True,  True]],
#              fill_value=999999)

然后我们可以对X_masked 做任何我们想做的事情,比如取每一列的总和(沿着axis=0):

np.sum(X_masked, axis=0)
# masked_array(data=[2, 4, 6, --, --],
#              mask=[False, False],
#              fill_value=1e+20)

这一点很棒的是X_masked 只是X 的视图,而不是副本。

X_masked.base is X
# True

【讨论】:

以上是关于通过布尔掩码数组选择numpy数组的元素的主要内容,如果未能解决你的问题,请参考以下文章

如何对 NumPy 数组执行逐元素布尔运算 [重复]

NumPy 数组切片索引

Numpy 布尔型数组

为啥 Numpy 掩码数组有用?

python库之numpy学习---nonzero()用法

numpy:布尔索引和内存使用