Python numpy:花式索引“;“意外行为”奇特的索引似乎给出的结果是;转置;直觉上的预期
我对花式索引的行为有点困惑,请参见:Python numpy:花式索引“;“意外行为”奇特的索引似乎给出的结果是;转置;直觉上的预期,python,numpy,Python,Numpy,我对花式索引的行为有点困惑,请参见: >>> 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 = 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]])
这并没有遵循我们刚才提到的不直观的行为模式……它的行为“如预期的那样”。为什么?
为什么会出现这种行为,如何才能达到预期的行为?如果在任何先前的轴中存在非切片,行为似乎会发生变化:
>>> import numpy as np
>>> t = np.arange(2*2*3).reshape((2, 2, 3))
>>> t[1:2, :, [1, 2]] # 1 -> 1:2 (slicing)
array([[[ 7, 8],
[10, 11]]])
>>> t[1][:, [1, 2]]
array([[ 7, 8],
[10, 11]])
每
在简单情况下(即一个索引数组
和N-1个切片对象)它完全符合您的期望(将
重复应用基本切片)
在这种情况下,索引数组是[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。因此,当您运行结果的最后一个(即第二个)轴时,您将得到数组
数组([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]])
或(使用广播)
这实际上可能更接近您想要的,因为它可以推广到索引数组是一些任意列表的情况,如[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]])
因此,当您运行结果的最后一个(即第三个)轴时,您将得到数组
数组([[1,4],[7,10]])
和数组([[2,5],[8,11]])
这不是花哨的索引,这是。尝试
t[1,:,1:3]
@AshwiniChaudhary实际上,这是一种奇特的索引,因为在我的应用程序中,数组[1,2]
实际上是[1,5,9,10]
,正如您所看到的,它不是顺序的。我已经在“最小工作示例”中降低了问题的复杂性(因此可以用正常的顺序索引表示法来回答),但这并没有消除问题是使用花式索引的事实。@user89,对不起,我不确定。我猜t[1,:,(1,2)]
的解释方式与t[(1,1)的解释方式相同,:,(1,2)]
。也就是说,索引t[1,:,1]
然后t[1,:,2]
并沿第一个轴连接它们。使用索引数组时,这种行为更直观(即,t[arr]
其中arr[0]是轴0索引,arr[1]是轴1索引,依此类推)。
In [101]: t[:, :, [1, 2]][1]
Out[101]:
array([[ 7, 8],
[10, 11]])
In [102]: t[:, :, 1]
Out[102]:
array([[ 1, 4],
[ 7, 10]])
In [103]: t[:, :, 2]
Out[103]:
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