I have an np.ndarray
of shape (5, 5, 2, 2, 2, 10, 8)
named table
. I can succesfully slice it like this:
table[4, [0, 1], 1, 1, 1, slice(0, 10, None), slice(0, 8, None)]
table[4, [0, 1], 1, 1, 1, [0, 2], slice(0, 8, None)]
But for some reason when I try to specify three values for dimension 5 (of length 10) like this:
table[4, [0, 1], 1, 1, 1, [0, 2, 6], slice(0, 8, None)]
I get:
>>> IndexError: shape mismatch: indexing arrays could not be broadcast together with shapes (2,) (3,)
The same is for:
table[4, [0, 1, 4], 1, 1, 1, [0, 2], slice(0, 8, None)]
This does not happen with:
table[4, [0, 1, 4], 1, 1, 1, slice(0, 10, None), slice(0, 8, None)]
table[4, [1, 0, 4], 1, 1, 1, slice(0, 10, None), slice(0, 8, None)]
which output the correct result.
I tried to read similar questions here on broadcasting but I was still confused why Numpy
can't make sense of this slice notation. Why does it act all puzzled when I give it more than two points along an axis to slice with when there's already another array in the indices?
The fact that you use
slice
instead of:
doesn't matter; same for the fact that the trailing slices don't have to be specified.This has an advanced indexing array/list of length 2 - the other dimensions are either scalars or slices. So they disappear or 'pass through'.
Here you have two advanced indexing lists - both length 2, so they 'broadcast' together to select 2 values (I think of this as a kind of 'diagonal').
Same as before but with a length 3 list.
But when the 2 lists have different length you get an error:
If one list is (2,1), then it works - it selects 2 in one dimension, and 3 in the other:
In indexing, 'broadcasting' follows the same rules as when adding (or multiplying) arrays.
edit
Look at a simpler 2d array:
If I index with 2 (2,) arrays I get 2 values:
But if I index with a (2,1) and (2,), I get a (2,2) shape result. Note where the [1,5] values are:
ix_
is a handy tool for constructing such a "cartesian" set of indexing arrays. For example 3 lists I get:Together those will select a block of shape (2,3,2) from a 3d (or larger) array.
Formally this is described in https://numpy.org/doc/stable/user/basics.indexing.html#advanced-indexing
(Your slices are all at the end. There is a nuance to this indexing when slices occur in the middle. See the subsection about
Combining advanced and basic indexing
if that arises.)