切片3d numpy数组返回奇怪的形状

时间:2015-07-14 18:29:44

标签: python arrays 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)

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

2 个答案:

答案 0 :(得分:5)

slice = test[0, :, coords]

是简单的索引,实际上说"取第一个坐标的第0个元素,所有第二个坐标,以及第三个坐标的第[1,3,4]个"。或者更确切地说,取坐标(0,无论如何,1)并使它成为我们的第一行,(0,无论如何,2)并使它成为我们的第二行,并且(0,无论如何,3)并使其成为我们的第三行。有5个whatevers,所以你最终得到(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个元素,即行。

答案 1 :(得分:4)

http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#combining-advanced-and-basic-indexing

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

test[0, :, coords]

索引coords首先出现[0,:],然后生成(3,5)

  

了解情况的最简单方法可能是考虑结果形状。索引操作分为两部分,即由基本索引(不包括整数)定义的子空间和来自高级索引部分的子空间。 [在这种情况下]

     

高级索引由切片,省略号或新轴分隔。例如x [arr1,:,arr2]。   ....高级索引操作产生的维度首先出现在结果数组中,然后是子空间维度。

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

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

How does numpy order array slice indices?

[:]中的test[0][:][coords]无效。 test[0][:,coords]生成所需的(5,3)结果。

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]])