Indexing numpy multidimensional arrays depends on a slicing method

雨燕双飞 提交于 2019-12-12 13:01:42

问题


I have a 3-D array. When I take a 2-D slice of it the result depends on whether it is indexed with a list or with a slice. In the first case the result is transposed. Didn't find this behaviour in the manual.

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

Could anyone point a rationale for this?


回答1:


As I understand it, NumPy is following the axis numbering philosophy when it spits out the result when given a list/tuple-like index.

array([[[1, 1, 1],
        [2, 2, 2]],

       [[3, 3, 3],
        [4, 4, 4]]])

When you already specify the first two indices (x[0, :, ]), now the next question is how to extract the third dimension. Now, when you specify a tuple (0,1), it first extracts the 0th slice axis wise, so it gets [1, 2] since it lies in 0th axis, next it extracts 1st slice likewise and stacks below the already existing row [1, 2].

[[1, 1, 1],          array([[1, 2],
 [2, 2, 2]]  =====>         [1, 2]])

(visualize this stacking as below (not on top of) the already existing row since axis-0 grows downwards)

Alternatively, it is following the slicing philosophy (start:stop:step) when slice(n) is given for the index. Note that using slice(2) is essentially equal to 0:2 in your example. So, it extracts [1, 1] first, then [2, 2]. Note, here to how [1, 1] comes on top of [2, 2], again following the same axis philosophy here since we didn't leave the third dimension yet. This is why this result is the transpose of the other.

array([[1, 1],
       [2, 2]])

Also, note that starting from 3-D arrays this consistency is preserved. Below is an example from 4-D array and the slicing results.

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



回答2:


Because you are actually using advanced indexing when you use [0,1]. From the docs:

Combining advanced and basic indexing

When there is at least one slice (:), ellipsis (...) or np.newaxis in the index (or the array has more dimensions than there are advanced indexes), then the behaviour can be more complicated. It is like concatenating the indexing result for each advanced index element

In the simplest case, there is only a single advanced index. A single advanced index can for example replace a slice and the result array will be the same, however, it is a copy and may have a different memory layout. A slice is preferable when it is possible.

Pay attention to the two parts I've bolded above.

In particular, in this construction:

>>> x[0,:,[0,1]]
array([[1, 2],
       [1, 2]])

Is the case where there is at least once "slice, ellipsisi, or np.newaxis" in the index, and the behavior is like concatenating the indexing result for each advanced index element. So:

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

However, this construction is like the simple case: there is only a single advanced index, so it acts like a slice:

>>> x[0,:,slice(2)]
array([[1, 1],
       [2, 2]])
>>> x[slice(0,1),:,slice(2)]
array([[[1, 1],
        [2, 2]]])

Although note, that the later is actually three dimensional because the first part of the index acted as a slice, it's 3 slices so three dimensions.



来源:https://stackoverflow.com/questions/43584813/indexing-numpy-multidimensional-arrays-depends-on-a-slicing-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!