2

Consider the following numpy array.

a = np.random.randn(10, 3, 20)

When I index the array as follow, it produces another array with expected shape

b = a[0, :, 0:5]
b.shape = (3, 5)

But when I index it with another numpy array but with similar elements, it produces a different array, which is transpose of the above result.

j = np.arange(0, 5, 1)
b = a[0, :, j]
b.shape = (5, 3)

I couldn't understand why this is the case.

Habtie27
  • 35
  • 8
  • Quite interesting. I'm observing this behaviour as well, but I'm not enough of a numpy expert to understand the cause. I'll poke around and see if I can determine more. –  Mar 15 '22 at 21:15
  • 1
    It's subtle. The second example is concatenating a set of slices. If you print `a[0,:,0]`, you'll see a 3-element slice, equal to the first row of the final `b`. Same with `a[0,:,1]`. The magic indexing takes those 5 3-element slices and returns then in a new array. A set of 5 slices is different from the array subset in `a[0,:,0:5]`. – Tim Roberts Mar 15 '22 at 21:17
  • 1
    So it seems like both versions are actually just tranposed version of the eachother. –  Mar 15 '22 at 21:20
  • I would love to mark this reply as an accepted answer. – Habtie27 Mar 15 '22 at 21:25
  • Isn't this still the implicit transposing of mixed indexing 'bug'? Compare `a[0, :, j]` vs `a[0][:,j]` discussed [here](https://stackoverflow.com/a/35306427/14277722) and [here](https://stackoverflow.com/a/35020886/14277722) – Michael Szczesny Mar 15 '22 at 21:37
  • @Habtie27 I included Tim's writup and an observation of my own in an answer. Feel free to check it out :) –  Mar 15 '22 at 21:38
  • @Michael I agree that it is extremely unintuitive, at least. –  Mar 15 '22 at 21:39
  • 1
    @richardec Thanks! I accepted it as a valid answer. – Habtie27 Mar 15 '22 at 22:47
  • 2
    Mixed advanced and basic indexing bites again :) https://numpy.org/doc/stable/user/basics.indexing.html#combining-advanced-and-basic-indexing – hpaulj Mar 15 '22 at 23:13
  • @hpaulj I suspected if it was something like that... –  Mar 15 '22 at 23:13

1 Answers1

1

Tim Roberts summarized it excellently in the comments, which I'll quote here in case the comments are cleaned up:

It's subtle. The second example is concatenating a set of slices. If you print a[0,:,0], you'll see a 3-element slice, equal to the first row of the final b. Same with a[0,:,1]. The magic indexing takes those 5 3-element slices and returns then in a new array. A set of 5 slices is different from the array subset in a[0,:,0:5].

In addition, if you notice, the two different indexing methods actually produce equivalent results; they're just transposed versions of each other. So a[0, :, np.arange(5)] == a[0, :, 0:5].T and a[0, :, np.arange(5)].T == a[0, :, 0:5].