2017-02-18 70 views
4

我想對行和列應用布爾型掩碼。用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])

+0

高級索引混合不工作,你認爲它的工作方式。請參閱http://stackoverflow.com/questions/30609734/numpy-ndarray-advanced-indexing/30609884#30609884瞭解大部分情況,除了使用整數數組而非布爾數組。 – user2357112

+0

另請參閱[索引文檔](https://docs.scipy.org/doc/numpy/user/basics.indexing.html),瞭解NumPy索引工作原理的全部細節(減去幾個奇怪的,未記錄的大多數案例爲了向後兼容)。 – user2357112

回答

3

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]]) 

的正確組合便利的工具,有效的爲第1軸和行向量的列向量其次,共同定義所需的矩形值。

但是試圖廣播這樣布爾數組不起作用: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])]

+0

啊,'ix_'也適用於布爾數組。有用的信息 – MSeifert

+0

這對我來說也是新的。 – hpaulj

+0

呵,那有用嗎?奇怪的。它在['np.ix_'本身](https://docs.scipy.org/doc/numpy/reference/generated/numpy.ix_.html)的文檔中沒有提及,並且按照' np.ix_'文檔會產生完全不同的結果。 – user2357112

1

一個解決方案是使用連續的整數索引並獲得例如整數從np.where

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

或@ user2357112在np.ix_可能被使用的評論中指出。例如:

>>> 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]]) 
+0

'np.ix_'幫助,如果你首先從布爾轉換爲整數索引數組。我一直希望'np.ix_'更加靈活。它可以做得比現在多得多。 – user2357112

+0

是的,我正在考慮'X [np.ix_(np.where(mask1)[0],np.where(mask2)[0])]''但我發現有點難以消化。 :) – MSeifert

+0

謝謝,我已經掌握了新的自己。它甚至可能只是做'X [mask1] [:, mask2]',它對我來說看起來是一個簡單的方法,但我聽說''['不是要走的路。 – tarashypka

-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) 
+0

numpy中的'masking'有兩種用法。一種是用布爾「掩碼」進行索引。另一個是構建一個'np.ma'的Masked Array。,就像你一樣。索引更常見。 – hpaulj

相關問題