切片三维numpy数组返回奇怪的形状



如果我用一组坐标切片一个二维数组

>>> test = np.reshape(np.arange(40),(5,8))
>>> coords = np.array((1,3,4))
>>> slice = test[:, coords]

那么我的切片的形状就是我所期望的

>>> slice.shape
(5, 3)

但如果我用3d阵列重复这个

>>> test = np.reshape(np.arange(80),(2,5,8))
>>> slice = test[0, :, coords]

那么现在的形状是

>>> slice.shape
(3, 5)

这些不同是有原因的吗?分离指数会返回我所期望的形状

>>> slice = test[0][:][coords]
>>> slice.shape
(5, 3)

为什么这些视图会有不同的形状?

slice = test[0, :, coords]

是简单的索引,实际上是说"取第一个坐标的第0个元素、所有第二个坐标和第三个坐标的[1,3,4]"。或者更准确地说,取坐标(0,whatever,1(,使其成为我们的第一行,(0,whatever,2(,使它成为我们的第二行,以及(0,anyever,3(,并使它成为第三行。有5个凡是,所以你最终得到(3,5(。

你举的第二个例子是这样的:

slice = test[0][:][coords]

在这种情况下,您看到的是一个(5,8(数组,然后取第1、第3和第4个元素,即第1、3和4行,最后得到的是(5,3(数组。

编辑讨论2D案例:

在2D情况下,其中:

>>> test = np.reshape(np.arange(40),(5,8))
>>> test
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, 36, 37, 38, 39]])

行为是相似的。

案例1:

>>> test[:,[1,3,4]]
array([[ 1,  3,  4],
       [ 9, 11, 12],
       [17, 19, 20],
       [25, 27, 28],
       [33, 35, 36]])

只是简单地选择列1,3和4。

案例2:

>>> test[:][[1,3,4]]
array([[ 8,  9, 10, 11, 12, 13, 14, 15],
       [24, 25, 26, 27, 28, 29, 30, 31],
       [32, 33, 34, 35, 36, 37, 38, 39]])

正在获取数组的第1个、第3个和第4个元素,这些元素是行。

http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#combining-高级和基本索引

这些文档讨论了高级索引和基本索引相结合的复杂性。

test[0, :, coords]

索引coords在前,[0,:]在后,生成(3,5)

理解这种情况最简单的方法可能是根据结果的形状进行思考。索引操作有两个部分,由基本索引(不包括整数(定义的子空间和来自高级索引部分的子空间。

高级索引由切片、省略号或newaxis分隔。例如x[ar1,:,arr2]。……高级索引操作产生的维度在结果数组中排名第一,然后是子空间维度。

我记得在之前的SO问题中讨论过这种索引,但它需要一些挖掘才能找到

https://stackoverflow.com/a/28353446/901925Why does the order of dimensions change with boolean indexing?

numpy如何排序数组切片索引?


test[0][:][coords]中的[:]不起任何作用。CCD_ 7产生期望的CCD_。

In [145]: test[0,:,[1,2,3]]   # (3,5) array
Out[145]: 
array([[ 1,  9, 17, 25, 33],   # test[0,:,1]
       [ 2, 10, 18, 26, 34],
       [ 3, 11, 19, 27, 35]])
In [146]: test[0][:,[1,2,3]]   # same values but (5,3)
Out[146]: 
array([[ 1,  2,  3],
       [ 9, 10, 11],
       [17, 18, 19],
       [25, 26, 27],
       [33, 34, 35]])
In [147]: test[0][:][[1,2,3]]   # [:] does nothing; select 3 from 2nd axis
Out[147]: 
array([[ 8,  9, 10, 11, 12, 13, 14, 15],
       [16, 17, 18, 19, 20, 21, 22, 23],
       [24, 25, 26, 27, 28, 29, 30, 31]])
In [148]: test[0][[1,2,3]]   # same as test[0,[1,2,3],:]
Out[148]: 
array([[ 8,  9, 10, 11, 12, 13, 14, 15],
       [16, 17, 18, 19, 20, 21, 22, 23],
       [24, 25, 26, 27, 28, 29, 30, 31]])

最新更新