# [Numpy-discussion] Numpy Advanced Indexing Question

Stéfan van der Walt stefan@sun.ac...
Thu Jul 17 03:16:51 CDT 2008

Hi Robert

2008/7/17 Robert Kern <robert.kern@gmail.com>:
> In [42]: smallcube = cube[idx_i,idx_j,idx_k]

Fantastic -- a good way to warm up the brain-circuit in the morning!
Is there an easy-to-remember rule that predicts the output shape of
the operation above?  I'm trying to imaging how the output would
change if I altered the dimensions of idx_i or idx_j, but it's hard.

It looks like you can do all sorts of interesting things by
manipulation the indices.  For example, if I take

In [137]: x = np.arange(12).reshape((3,4))

I can produce either

In [138]: x[np.array([[0,1]]), np.array([[1, 2]])]
Out[138]: array([[1, 6]])

or

In [140]: x[np.array([[0],[1]]), np.array([[1], [2]])]
Out[140]:
array([[1],
[6]])

and even

In [141]: x[np.array([[0],[1]]), np.array([[1, 2]])]
Out[141]:
array([[1, 2],
[5, 6]])

or its transpose

In [143]: x[np.array([[0,1]]), np.array([[1], [2]])]
Out[143]:
array([[1, 5],
[2, 6]])

Is it possible to separate the indexing in order to understand it
better?  My thinking was

cube_i = cube[idx_i,:,:].squeeze()
cube_j = cube_i[:,idx_j,:].squeeze()
cube_k = cube_j[:,:,idx_k].squeeze()

Not sure what would happen if the original array had single dimensions, though.

Back to the original problem:

In [127]: idx_i.shape
Out[127]: (10, 1, 1)

In [128]: idx_j.shape
Out[128]: (1, 15, 1)

In [129]: idx_k.shape
Out[129]: (10, 15, 7)

For the constant slice case, I guess idx_k also have been (1, 1, 7)?

The construction of the cube could probably be done using only

cube.flat = np.arange(nk)

Fernando is right: this is good food for thought and excellent
cookbook material!

Regards
Stéfan