我对花式索引的行为有点困惑,请参阅:
>>> t = np.arange(2*2*3).reshape((2, 2, 3))
>>> t
array([[[ 0, 1, 2],
[ 3, 4, 5]],
[[ 6, 7, 8],
[ 9, 10, 11]]])
>>> t[1, :, [1, 2]]
array([[ 7, 10],
[ 8, 11]])
我认为在使用 t[1, :, [1, 2]]
建立索引后我会得到数组:
array([[ 7, 8],
[10, 11]])
但是我得到了转置,如上所示。
此外,请考虑以下事项:
>>> t[:, :, [1, 2]][1]
array([[ 7, 8],
[10, 11]])
这不符合我们刚刚提到的不直观的行为模式……这“符合预期”。为什么?
为什么我会出现这种行为,我怎样才能得到我预期的行为?
最佳答案
根据 the docs ,
In simple cases (i.e. one indexing array and N - 1 slice objects) it does exactly what you would expect (concatenation of repeated application of basic slicing).
在这种情况下,索引数组是 [1, 2],切片对象是 1
和 :
(或更准确地说, slice(1,2)
和 slice(None)
):
所以结果是切片的串联
In [43]: t[1,:,1]
Out[43]: array([ 7, 10])
In [44]: t[1,:,2]
Out[44]: array([ 8, 11])
还要注意 t[1, :, [1,2]]
的形状将是 (2,2) 因为标量 1
删除 0 轴和 :
跨越所有轴 1(长度为 2)和 [1,2]
长度为 2。因此,当您遍历结果的最后一个(即第二个)轴时,您会得到数组
array([ 7, 10])
和 array([ 8, 11])
.
In [45]: t[1, :, [1,2]]
Out[45]:
array([[ 7, 10],
[ 8, 11]])
获得所需结果的最简单方法是使用基本切片,
In [45]: t[1, :, 1:3]
Out[45]:
array([[ 7, 8],
[10, 11]])
另一种使用“奇特”整数索引的方法是:
In [121]: t[1, [(0,0),(1,1)], [1,2]]
Out[121]:
array([[ 7, 8],
[10, 11]])
或(使用广播)
In [154]: t[1, [[0],[1]], [1,2]]
Out[154]:
array([[ 7, 8],
[10, 11]])
这实际上可能更接近你想要的,因为它可以推广到你的索引数组是一些任意列表的情况,比如 [1, 5, 9, 10]
.
In [157]: t = np.arange(2*2*11).reshape(2,2,11)
In [158]: t[1, [[0],[1]], [1,5,9,10]]
Out[158]:
array([[23, 27, 31, 32],
[34, 38, 42, 43]])
同样的规则适用于
In [101]: t[:, :, [1, 2]][1]
Out[101]:
array([[ 7, 8],
[10, 11]])
首先注意t[:, :, [1, 2]]
的形状将是 (2,2,2)。结果将是基本切片的串联
In [102]: t[:, :, 1]
Out[102]:
array([[ 1, 4],
[ 7, 10]])
In [103]: t[:, :, 2]
Out[103]:
array([[ 2, 5],
[ 8, 11]])
因此,当您遍历结果的最后一个(即第三个)轴时,您会得到数组
array([[ 1, 4], [ 7, 10]])
和 array([[ 2, 5], [ 8, 11]])
.
In [107]: np.allclose(t[:, :, [1,2]], np.dstack([np.array([[ 1, 4], [ 7, 10]]), np.array([[ 2, 5], [ 8, 11]])]))
Out[107]: True
关于python - numpy: fancy indexing "unexpected behaviour"-- fancy indexing 似乎给出的结果是直观预期的 "transpose",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26435695/