1

I am trying to understand numpy's combined slicing and indexing concept, however I am not sure how to correctly get the below results from numpy's output (by hand so that we can understand how numpy process combined slicing and indexing, which one will be process first?):

>>> import numpy as np
>>> a=np.arange(12).reshape(3,4)
>>> a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> i=np.array([[0,1],[2,2]])
>>> a[i,:]
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7]],

       [[ 8,  9, 10, 11],
        [ 8,  9, 10, 11]]])
>>> j=np.array([[2,1],[3,3]])
>>> a[:,j]
array([[[ 2,  1],
        [ 3,  3]],

       [[ 6,  5],
        [ 7,  7]],

       [[10,  9],
        [11, 11]]])
>>> aj=a[:,j]
>>> aj.shape
(3L, 2L, 2L)

I am bit confused about how aj's shape becomes (3,2,2) with the above output, any detailed explanations are very appreciated, thanks!

Roy Li
  • 51
  • 9

2 Answers2

2

Whenever you use an array of indices, the result has the same shape as the indices; for example:

>>> x = np.ones(5)
>>> i = np.array([[0, 1], [1, 0]])
>>> x[i]
array([[ 1.,  1.],
       [ 1.,  1.]])

We've indexed with a 2x2 array, and the result is a 2x2 array. When combined with a slice, the size of the slice is preserved. For example:

>>> x = np.ones((5, 3))
>>> x[i, :].shape
(2, 2, 3)

Where the first example was a 2x2 array of items, this example is a 2x2 array of (length-3) rows.

The same is true when you switch the order of the slice:

>>> x = np.ones((5, 3))
>>> x[:, i].shape
(5, 2, 2)

This can be thought of as a list of five 2x2 arrays.

Just remember: when any dimension is indexed with a list or array, the result has the shape of the indices, not the shape of the input.

jakevdp
  • 77,104
  • 11
  • 125
  • 160
  • Thank you for the answer, could you please recommend any good source of reference for numpy's indexing and slicing? The numpy's reference manual seems not detailed enough. – Roy Li Oct 05 '16 at 13:34
  • 1
    I discuss it in detail in my book which will be freely available soon as a collection of Jupyter notebooks: https://github.com/jakevdp/PythonDataScienceHandbook – jakevdp Oct 05 '16 at 14:11
1

a[:,j][0] is equivalent to a[0,j] or [0, 1, 2, 3][j] which gives you [[2, 1], [3, 3]])

a[:,j][1] is equivalent to a[1,j] or [4, 5, 6, 7][j] which gives you [[6, 5], [7, 7]])

a[:,j][2] is equivalent to a[2,j] or [8, 9, 10, 11][j] which gives you [[10, 9], [11, 11]])

Julien
  • 13,986
  • 5
  • 29
  • 53