2017-03-17 152 views
0

我:2D numpy的數組索引花式+屏蔽

import numpy as np 
a = np.array([[ 4, 99, 2], 
       [ 3, 4, 99], 
       [ 1, 8, 7], 
       [ 8, 6, 8]]) 

爲什麼

a[[True, True, False, False], [1,2]] 

等於

array([99, 99]) 

而且不

array([99, 2], 
     [4, 99]) 

因爲我選擇使用布爾掩碼和使用花式索引的第二和第三列的前兩行?特別是因爲打電話

a[[True, True, False, False],:][:, [1,2]] 

給我我的預期結果。我猜測它的某種廣播規則,但對我來說並不明顯。謝謝!

+0

我得到一個'IndexError:形狀不匹配:索引陣列不能與形狀(4)一起廣播(2,)'對於您的查詢... –

+0

這只是下標索引,從每個dim的每個索引中選取一組索引中的每個元素。所以,它的索引用'(0,1)'[0從布爾數組的第一個TRUE elem,1從int索引數組的第一個元素]爲第一個elem和'(1,2)'爲第二個。 – Divakar

+0

@WillemVanOnsem我認爲OP意味着使用布爾**陣列**不只是一個普通的Python列表索引。如果你將它們轉換爲數組,那麼你會得到OP的結果。 – kmario23

回答

1

布爾矩陣或列表計算,就好像where有它轉換爲索引陣列:

In [285]: a[[True,True,False,False],[1,2]] 
Out[285]: array([99, 99]) 

In [286]: a[np.where([True,True,False,False]),[1,2]] 
Out[286]: array([[99, 99]]) 

In [287]: np.where([True,True,False,False]) 
Out[287]: (array([0, 1], dtype=int32),) 

In [288]: a[[0,1], [1,2]] 
Out[288]: array([99, 99]) 

所以這是採摘a[0,1]a[1,2],一個 '配對' 塞萊ction。

該塊索引與陣列(或列表當量)彼此抵靠的是廣播,以產生(2,2)陣列:

In [289]: a[np.ix_([0,1], [1,2])] 
Out[289]: 
array([[99, 2], 
     [ 4, 99]]) 
In [290]: a[[[0],[1]], [1,2]] 
Out[290]: 
array([[99, 2], 
     [ 4, 99]]) 

這種情況相當於一個2級索引:a[[0,1],:][:,[1,2]]

我正在使用np版本12.布爾指數在最近的版本中發生了一些變化。例如,如果布爾的長度不正確,它會運行,但會發出警告(這部分是新的)。

In [349]: a[[True,True,False],[1,2]] 
/usr/local/bin/ipython3:1: VisibleDeprecationWarning: boolean index did not match indexed array along dimension 0; dimension is 4 but corresponding boolean dimension is 3 
    #!/usr/bin/python3 
Out[349]: array([99, 99]) 

爲13節的變化中描述:

https://docs.scipy.org/doc/numpy-dev/release.html#boolean-indexing-changes

+0

你怎麼沒有通過使用普通的python列表索引來獲得'IndexError'? – kmario23

+1

我正在使用np.version:1.12.0。布爾索引處理的方式發生了變化。 – hpaulj

+0

謝謝!這個解釋爲我清除了它。 – kuan

1

我覺得它的工作原理如下所示:

In [284]: a 
Out[284]: 
array([[ 4, 99, 2], 
     [ 3, 4, 99], 
     [ 1, 8, 7], 
     [ 8, 6, 8]]) 

In [286]: bo 
Out[286]: array([ True, True, False, False], dtype=bool) 

In [287]: boc 
Out[287]: array([1, 2]) 

現在,一旦我們的索引a與布爾面具bo,我們得到:

In [285]: a[bo] 
Out[285]: 
array([[ 4, 99, 2], 
     [ 3, 4, 99]]) 

因爲,bo計算結果爲[1, 1, 0, 0],這將只需選擇a的前兩行。

現在,我們運用組合boc[1, 2]與行選擇面膜bo

In [288]: a[bo, boc] 
Out[288]: array([99, 99]) 

這裏,掩模boc被施加到已經提取的行。它從第一行中選擇第二個元素,從第二個行中選擇第三個元素,產生[99, 99]

但是,有趣的是,如果你這樣做:

In [289]: a[1, [1, 2]] 
Out[289]: array([ 4, 99]) 

在這種情況下,numpy的廣播產生的指數[(1,1), (1,2)]