具有numpy的多轴上的布尔遮罩

时间:2017-02-18 00:04:53

标签: python numpy

我想对行和列应用布尔掩码。

使用

X = np.array([[1,2,3],[4,5,6]])
mask1 = np.array([True, True])
mask2 = np.array([True, True, False])
X[mask1, mask2]

我希望输出为

array([[1,2],[4,5]])

而不是

array([1,5])

众所周知

X[:, mask2]

可以在这里使用,但这不是一般情况的解决方案。

我想知道它是如何工作的,为什么在这种情况下结果是array([1,5])

4 个答案:

答案 0 :(得分:5)

X[mask1, mask2]Boolean Array Indexing Doc中描述为等同于

In [249]: X[mask1.nonzero()[0], mask2.nonzero()[0]]
Out[249]: array([1, 5])
In [250]: X[[0,1], [0,1]]
Out[250]: array([1, 5])

实际上它会给你X[0,0]X[1,1](将0和1配对)。

你想要的是:

In [251]: X[[[0],[1]], [0,1]]
Out[251]: 
array([[1, 2],
       [4, 5]])

np.ix_是一个方便的工具,用于创建正确的维度组合

In [258]: np.ix_([0,1],[0,1])
Out[258]: 
(array([[0],
        [1]]), array([[0, 1]]))
In [259]: X[np.ix_([0,1],[0,1])]
Out[259]: 
array([[1, 2],
       [4, 5]])

这实际上是第一轴的列向量和第二轴的行向量,一起定义了所需的矩形值。

但尝试广播这样的布尔数组不起作用:X[mask1[:,None], mask2]

但该参考部分说:

  

使用obj.nonzero()类比可以最好地理解组合多个布尔索引数组或布尔与整数索引数组。函数ix_也支持布尔数组,并且可以毫无意外地工作。

In [260]: X[np.ix_(mask1, mask2)]
Out[260]: 
array([[1, 2],
       [4, 5]])
In [261]: np.ix_(mask1, mask2)
Out[261]: 
(array([[0],
        [1]], dtype=int32), array([[0, 1]], dtype=int32))

ix_的布尔部分:

    if issubdtype(new.dtype, _nx.bool_):
        new, = new.nonzero()

所以它适用于像X[np.ix_(mask1, [0,2])]

这样的混音

答案 1 :(得分:1)

一种解决方案是使用顺序整数索引并获取整数,例如来自np.where

>>> X[:, np.where(mask1)[0]][np.where(mask2)[0]]
array([[1, 2],
       [4, 5]])

或者在评论np.ix_中指出的@ user2357112也可以使用。例如:

>>> X[np.ix_(np.where(mask1)[0], np.where(mask2)[0])]
array([[1, 2],
       [4, 5]])

另一个想法是播放你的面具,然后一步完成需要重新塑造:

>>> X[np.where(mask1[:, None] * mask2)]
array([1, 2, 4, 5])

>>> X[np.where(mask1[:, None] * mask2)].reshape(2, 2)
array([[1, 2],
       [4, 5]])

答案 2 :(得分:0)

从广义上讲,您的问题是查找包含某些行和列的数组的子部分

main_array = np.array([[1,2,3],[4,5,6]])
mask_ax_0 = np.array([True, True]) # about which rows, i want
mask_ax_1 = np.array([True, True, False]) # which columns, i want

答案:

mask_2d = np.logical_and(mask_ax_0.reshape(-1,1), mask_ax_1.reshape(1,-1))
sub_array = main_array[mask_2d].reshape(np.sum(mask_ax_0), np.sum(mask_ax_1))
print(sub_array)

答案 3 :(得分:-2)

您应该使用numpy.ma模块。 特别是,您可以使用mask_rowcols

X = np.array([[1,2,3],[4,5,6]])
linesmask = np.array([True, True])
colsmask = np.array([True, True, False])

X = X.view(ma.MaskedArray)
for i in range(len(linesmask)):
    X.mask[i][0] = not linemask[i]
for j in range(len(colsmask)):
    X.mask[0][j] = not colsmask[j]
X = ma.mask_rowcols(X)