Numpy 高级选择不起作用
Numpy advanced selection not working
谁能帮我理解为什么有时高级选择不起作用以及我可以做些什么来让它起作用(第二种情况)?
>>> 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 ],
你想要
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]]
意味着 "take all parts b[i, j]
of b
where i
is 0 or 1 and j
is 0, 1, or 2"。这是一个合理的错误,考虑到当你在索引表达式中有一个列表时它似乎是这样工作的,比如
b[:, [1, 3, 5], 2]
实际上,对于数组A
和一维整数数组I
和J
,A[I, J]
是一个数组,其中
A[I, J][n] == A[I[n], J[n]]
这以自然的方式推广到更多索引数组,例如
A[I, J, K][n] == A[I[n], J[n], K[n]]
和高维索引数组,所以如果I
和J
是二维的,那么
A[I, J][m, n] == A[I[m, n], J[m, n]]
它也将广播规则应用于索引数组,并将索引中的列表转换为数组。这比您预期的要强大得多,但这意味着要完成您想要做的事情,您需要
b[[[0],
[1]], [[0, 1, 2]]]
np.ix_
是一个帮手,可以为您做这些,因此您不必写一打括号。
我认为您误解了这种情况下的高级选择语法。我使用了您的示例,只是将其缩小以便于查看。
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 ]]]
谁能帮我理解为什么有时高级选择不起作用以及我可以做些什么来让它起作用(第二种情况)?
>>> 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 ],
你想要
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]]
意味着 "take all parts b[i, j]
of b
where i
is 0 or 1 and j
is 0, 1, or 2"。这是一个合理的错误,考虑到当你在索引表达式中有一个列表时它似乎是这样工作的,比如
b[:, [1, 3, 5], 2]
实际上,对于数组A
和一维整数数组I
和J
,A[I, J]
是一个数组,其中
A[I, J][n] == A[I[n], J[n]]
这以自然的方式推广到更多索引数组,例如
A[I, J, K][n] == A[I[n], J[n], K[n]]
和高维索引数组,所以如果I
和J
是二维的,那么
A[I, J][m, n] == A[I[m, n], J[m, n]]
它也将广播规则应用于索引数组,并将索引中的列表转换为数组。这比您预期的要强大得多,但这意味着要完成您想要做的事情,您需要
b[[[0],
[1]], [[0, 1, 2]]]
np.ix_
是一个帮手,可以为您做这些,因此您不必写一打括号。
我认为您误解了这种情况下的高级选择语法。我使用了您的示例,只是将其缩小以便于查看。
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 ]]]