2016-04-20 57 views
2

有人可以幫我理解爲什麼有時候高級選擇不起作用,我能做些什麼才能使它起作用(第二種情況)?Numpy高級選擇不起作用

>>> import numpy as np 
>>> b = np.random.rand(5, 14, 3, 2) 

# advanced selection works as expected 
>>> b[[0,1],[0,1]] 
array([[[ 0.7575555 , 0.18989068], 
     [ 0.06816789, 0.95760398], 
     [ 0.88358107, 0.19558106]], 

     [[ 0.62122898, 0.95066355], 
     [ 0.62947885, 0.00297711], 
     [ 0.70292323, 0.2109297 ]]]) 

# doesn't work - why? 
>>> b[[0,1],[0,1,2]] 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: shape mismatch: objects cannot be broadcast to a single shape 

# but this seems to work 
>>> b[:,[0,1,2]] 
array([[[[ 7.57555496e-01, 1.89890676e-01], 
     [ 6.81678915e-02, 9.57603975e-01], 
     [ 8.83581071e-01, 1.95581063e-01]], 

     [[ 2.24896112e-01, 4.77818599e-01], 
     [ 4.29313861e-02, 8.61578045e-02], 
     [ 4.80092364e-01, 3.66821618e-01]], 
... 

更新

分手的選擇似乎是解決這個問題,但我不能確定爲什麼這是必要的(或者,如果有一個更好的方式來做到這一點)。

>>> b.shape 
(5, 14, 3, 2) 
>>> b[[0,1]].shape 
(2, 14, 3, 2) 

# trying to separate indexing by dimension. 
>>> b[[0,1]][:,[0,1,2]] 
array([[[[ 0.7575555 , 0.18989068], 
     [ 0.06816789, 0.95760398], 
     [ 0.88358107, 0.19558106]], 

     [[ 0.22489611, 0.4778186 ], 
     [ 0.04293139, 0.0861578 ], 
+1

你覺得呢'B [[0,1],[0,1,2]]'應該做的事?如果你期望這樣做,那麼'b [[0,1],[0,1]]'最有可能沒有做你想做的事情,而你沒有注意到由於沒有噪聲錯誤信息。 – user2357112

+1

那麼,對於初學者來說,它不應該導致錯誤。 – orange

+1

該索引應從維度'0'選擇元素'0'和'1',並從維度'1'選擇'0','1'和'2'(對於其他後續維度選擇「片(無)」) 。 – orange

回答

5

你想

b[np.ix_([0, 1], [0, 1, 2])] 

你也需要做同樣的事情爲b[[0, 1], [0, 1]],因爲這不是真正在做什麼,你認爲它是:

b[np.ix_([0, 1], [0, 1])] 

問題這裏的高級索引與你所想象的完全不同。你犯了一個錯誤,認爲b[[0, 1], [0, 1, 2]]的意思是「採取b的所有部分b[i, j],其中i是0或1並且j是0,1或2」。這是一個合理犯的錯誤,考慮到它似乎工作方式,當你在索引表達式一個列表,像

b[:, [1, 3, 5], 2] 

其實,對於一個數組A和一維整數數組IJA[I, J]是陣列,其中

A[I, J][n] == A[I[n], J[n]] 

這概括在自然的方式來更索引陣列,因此,例如

A[I, J, K][n] == A[I[n], J[n], K[n]] 

和高維數組索引,所以如果IJ是二維的,然後

A[I, J][m, n] == A[I[m, n], J[m, n]] 

它也適用於廣播規則的數組索引,並在索引數組轉換列表。這是比你預期的要發生什麼更強大,但它意味着做你試圖做的,你需要像

b[[[0], 
    [1]], [[0, 1, 2]]] 

np.ix_是一個輔助,將做到這一點給你,讓你不」不得不寫十幾個括號。

+0

感謝您的全面而富有洞察力的解釋! – orange

+0

但是我如何在我的選擇中有':'時使用np.ix_。示例a [:, [0,1],[0,1,2]]當我嘗試一個[:,np.ix _([0,1],[0,1,2])]它只是抱怨。 – Nozdrum

+0

@Nozdrum:使用'np.arange(a.shape [0])'而不是':'(使用'np.ix_'),或者使用':2'和':3'來代替'[0,1 ]'和'[0,1,2]'(不含'np.ix_')。混合基本和高級索引是很奇怪和棘手的;除了最簡單的情況外,最好將基本和高級索引分開。 – user2357112

0

我想你誤解了這種情況下的高級選擇語法。我用你的例子,使它更小,以便更容易看到。

import numpy as np 
b = np.random.rand(5, 4, 3, 2) 

# advanced selection works as expected 
print b[[0,1],[0,1]] # http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html 
         # this picks the two i,j=0 (a 3x2 matrix) and i=1,j=1, another 3x2 matrix 

# doesn't work - why? 
#print b[[0,1],[0,1,2]] # this doesnt' work because [0,1] and [0,1,2] have different lengths 

print b[[0,1,2],[0,1,2]] # works 

輸出:

[[[ 0.27334558 0.90065184] 
    [ 0.8624593 0.34324983] 
    [ 0.19574819 0.2825373 ]] 

[[ 0.38660087 0.63941692] 
    [ 0.81522421 0.16661912] 
    [ 0.81518479 0.78655536]]] 
[[[ 0.27334558 0.90065184] 
    [ 0.8624593 0.34324983] 
    [ 0.19574819 0.2825373 ]] 

[[ 0.38660087 0.63941692] 
    [ 0.81522421 0.16661912] 
    [ 0.81518479 0.78655536]] 

[[ 0.65336551 0.1435357 ] 
    [ 0.91380873 0.45225145] 
    [ 0.57255923 0.7645396 ]]]