2016-04-20 58 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 ]]]