Numpy高级选择不起作用

时间:2016-04-20 03:58:26

标签: python numpy multidimensional-array matrix-indexing

有人可以帮助我理解为什么有时高级选择不起作用以及我能做些什么才能让它起作用(第二种情况)?

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

2 个答案:

答案 0 :(得分: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[i, j] b i为0或1且j为0,1 {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_是一个帮助你的人,所以你不必写十几个括号。

答案 1 :(得分: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 ]]]