[英]Indexing numpy multidimensional arrays depends on a slicing method
我有一个三维数组。 当我采用它的2-D切片时,结果取决于它是用列表索引还是用切片索引。 在第一种情况下,结果是转置的。 没有在手册中找到此行为。
>>> import numpy as np
>>> x = np.array([[[1,1,1],[2,2,2]], [[3,3,3],[4,4,4]]])
>>> x
array([[[1, 1, 1],
[2, 2, 2]],
[[3, 3, 3],
[4, 4, 4]]])
>>> x[0,:,[0,1]]
array([[1, 2],
[1, 2]])
>>> x[0,:,slice(2)]
array([[1, 1],
[2, 2]])
>>>
任何人都可以指出这个理由吗?
因为在使用[0,1]
时实际上正在使用高级索引 。 来自文档 :
结合高级和基本索引
当存在至少一个片(:
),省略号(...
)或np.newaxis
在索引(或阵列具有多个尺寸比有先进的索引),则行为可以是更复杂的。 这就像连接每个高级索引元素的索引结果一样在最简单的情况下,只有一个高级索引。 单个高级索引可以例如替换切片,并且结果数组将是相同的,但是,它是副本并且可以具有不同的存储器布局 。 当可能时,切片是优选的。
注意我上面加粗的两个部分。
特别是在这种结构中:
>>> x[0,:,[0,1]]
array([[1, 2],
[1, 2]])
是否在索引中至少有一次“slice,ellipsisi或np.newaxis”,并且行为就像连接每个高级索引元素的索引结果一样。 所以:
>>> x[0,:,[0]]
array([[1, 2]])
>>> x[0,:,[1]]
array([[1, 2]])
>>> np.concatenate((x[0,:,[0]], x[0,:,[1]]))
array([[1, 2],
[1, 2]])
但是,这种结构就像一个简单的例子:只有一个高级索引,所以它就像一个切片:
>>> x[0,:,slice(2)]
array([[1, 1],
[2, 2]])
>>> x[slice(0,1),:,slice(2)]
array([[[1, 1],
[2, 2]]])
虽然注意,后者实际上是三维的,因为索引的第一部分充当切片,它是3个切片,所以三个维度。
据我了解,NumPy遵循轴编号原则,当它给出一个list/tuple
like索引时吐出结果。
array([[[1, 1, 1],
[2, 2, 2]],
[[3, 3, 3],
[4, 4, 4]]])
当您已指定前两个索引( x[0, :, ]
)时,现在下一个问题是如何提取第三个维度。 现在,当你指定一个元组(0,1)
,它首先提取第0
个切片轴,因此它得到[1, 2]
因为它位于第0
个轴,然后它同样提取第1
切片并堆叠在已存在的行[1, 2]
。
[[1, 1, 1], array([[1, 2],
[2, 2, 2]] =====> [1, 2]])
(将此堆叠可视化为现有行的下方( 不在其上方 ),因为0轴向下增长)
或者,当为索引给出slice(n)
时,它遵循切片原理( start
: stop
: step
)。 请注意,在您的示例中,使用slice(2)
基本上等于0:2
。 因此,它首先提取[1, 1]
,然后提取[1, 1]
[2, 2]
。 注意,这里[1, 1]
如何在[2, 2]
[1, 1]
之上,再次遵循相同的轴哲学,因为我们还没有离开第三维。 这就是为什么这个结果是另一个的转置。
array([[1, 1],
[2, 2]])
另请注意,从3-D数组开始,这种一致性得以保留。 下面是4-D
数组和切片结果的示例。
In [327]: xa
Out[327]:
array([[[[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8]],
[[ 9, 10, 11],
[12, 13, 14],
[15, 16, 17]]],
[[[18, 19, 20],
[21, 22, 23],
[24, 25, 26]],
[[27, 28, 29],
[30, 31, 32],
[33, 34, 35]]]])
In [328]: xa[0, 0, :, [0, 1]]
Out[328]:
array([[0, 3, 6],
[1, 4, 7]])
In [329]: xa[0, 0, :, 0:2]
Out[329]:
array([[0, 1],
[3, 4],
[6, 7]])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.