[英]How does numpy order array slice indices?
我有一个形状的np.array data
(28,8,20),我只需要它的某些条目,所以我正在切片:
In [41]: index = np.array([ 5, 6, 7, 8, 9, 10, 11, 17, 18, 19])
In [42]: extract = data[:,:,index]
In [43]: extract.shape
Out[43]: (28, 8, 10)
到目前为止一切都那么好,一切都应该如此。 但是现在我只想看看第一行最后一个索引的前两个条目:
In [45]: extract[0,:,np.array([0,1])].shape
Out[45]: (2, 8)
等等,应该是(8,2)。 它改变了指数,即使我最后一次切片时没有! 根据我的理解,以下应采取相同的行动:
In [46]: extract[0,:,:2].shape
Out[46]: (8, 2)
......但它给了我我想要的东西! 但是,只要我有一个3D数组,这两种方法似乎都是等价的:
In [47]: extract[:,:,np.array([0,1])].shape
Out[47]: (28, 8, 2)
In [48]: extract[:,:,:2].shape
Out[48]: (28, 8, 2)
那么,如果我不仅需要前两个条目而且需要不规则列表,我该怎么办? 我当然可以在操作后转置矩阵,但这看起来非常违反直觉。 我的问题的一个更好的解决方案是这个(虽然可能有一个更优雅的):
In [64]: extract[0][:,[0,1]].shape
Out[64]: (8, 2)
这把我们带到了实际
我想知道这种行为的原因是什么? 无论谁决定它应该如何工作,可能比我更了解编程,并认为这在某些方面是一致的,我完全没有。 除非我有办法理解它,否则我可能会继续关注这个问题。
这是(高级)部分索引的情况。 有2个索引数组和1个切片
如果索引子空间是分开的(通过切片对象),则首先是广播的索引空间,然后是x的切片子空间。
http://docs.scipy.org/doc/numpy-1.8.1/reference/arrays.indexing.html#advanced-indexing
高级索引示例注意到,当ind_1
, ind_2
广播子空间的shape (2,3,4)
表示:
但是,x [:,ind_1,:,ind_2]具有形状(2,3,4,10,30,50),因为在索引子空间中没有明确的位置,因此它被添加到开头。 始终可以使用.transpose()在任何需要的位置移动子空间。
换句话说,这个索引与x[:, ind_1][[:,ind_2]
。 2个阵列共同操作以定义(2,3,4)
子空间。
在你的例子中, extract[0,:,np.array([0,1])]
被理解为意味着,选择一个(2,)
子空间([0]和[0,1]共同行动,而不是顺序) ,并以某种方式将其与中间维度相结合。
一个更精细的例子是extract[[1,0],:,[[0,1],[1,0]]]
,它产生一个(2,2,8)
数组。 这是第一维和最后一维的(2,2)
子空间,加上中间维。 另一方面, X[[1,0]][:,:,[[0,1],[1,0]]]
产生一个(2,8,2,2)
,从第一个和最后一个选择尺寸分开。
关键的区别在于索引选择是顺序操作还是联合操作。 [...] [...]语法已经可以按顺序运行。 高级索引为您提供了一种联合索引方式。
你是对的,这很奇怪。 我只能冒这个猜测。 我认为这与a[[0,1],[0,1],[0,1]].shape
是(2,)
而不是(2,2,2)
并且a[0,1,[0,1,2]]
实际上意味着a[[0,0,0],[1,1,1],[0,1,2]]
计算为array([a[0,1,0],a[0,1,1],a[0,1,2]])
。 也就是说,您逐步浏览每个维度的列表 - 索引,长度 - 一个列表和标量被广播以匹配最长的。
从概念上讲,这会使你的extract[0,:,[0,1]]
等同于extract[[0,0],[slice(None),slice(None)],[0,1]]
(该语法不是但是,如果您手动指定它,则不会被接受。 单步执行索引后,将评估为array([extract[0,slice(None),0],extract[0,slice(None),1])
。 每个内部提取都评估为一个形状(8,)
数组,因此完整的结果是形状(2,8)
。
总而言之,我认为广播的副作用是使所有维度都具有相同长度的索引列表,这导致:
广播也是如此。 这是我的假设,但我没有看到numpy
如何做到这一点的内部运作。 也许专家会提出更好的解释。
这个假设并不能解释为什么extract[:,:,[0,1]]
不会导致相同的行为。 我不得不假设只有前导“:”的情况是特殊的,以避免参与列表索引逻辑。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.