0

I am trying to perform non-consectuitive slicing of a multidimensional array like this (Matlab peudo code)

 A = B(:,:,[1,3],[2,4,6]) %A and B are two 4D matrices

But when I try to write this code in Python:

A = B[:,:,np.array([0,2]),np.array([1,3,5])] #A and B are two 4D arrays

it gives an error: IndexError: shape mismatch: indexing arrays could not be broadcast...

It should be noted that slicing for one dimension each time works fine!

7
  • 1
    You should include A and B in your question, as well as your expected output Commented Oct 30, 2018 at 21:09
  • 1
    What is B? list or numpy array? Commented Oct 30, 2018 at 21:09
  • 1
    That piece of code can't give you that error. The only indexing arrays are np.array([0,2]) and np.array([1,3]) which can be broadcast together, It wouldn't do what it does in matlab, and the indices are off, but it shouldn't give you that error. Please come up with a proper minimal reproducible example and run it to check that it reproduces your problem. Commented Oct 30, 2018 at 21:49
  • 2
    You need np.ix_. One relevant duplicate, another one. The top-voted answer to the former shows how to use it. Also don't forget that while MATLAB indices are 1-based, numpy indices are 0-based. Commented Oct 30, 2018 at 22:14
  • 1
    @AndrasDeak. I were wrong in the above code. The two indexing vectors are different in length. Commented Oct 30, 2018 at 22:15

1 Answer 1

2

In numpy, if you use more than one fancy index (i.e. array) to index different dimension of the same array at the same time, they must broadcast. This is designed such that indexing can be more powerful. For your situation, the simplest way to solve the problem is indexing twice:

B[:, :, [0,2]] [..., [1,3,5]]

where ... stands for as many : as possible.

Indexing twice this way would generate some extra data moving time. If you want to index only once, make sure they broadcast (i.e. put fancy indices on different dimension):

B[:, :, np.array([0,2])[:,None], [1,3,5]]

which will result in a X by Y by 2 by 3 array. On the other hand, you can also do

B[:, :, [0,2], np.array([1,3,5])[:,None]]

which will result in a X by Y by 3 by 2 array. The [1,3,5] axis is transposed before the [0,2] axis.

Yon don't have to use np.array([0,2]) if you don't need to do fancy operation with it. Simply [0,2] is fine.

np.array([0,2])[:,None] is equivalent to [[0],[2]], where the point of [:,None] is to create an extra dimension such that the shape becomes (2,1). Shape (2,) and (3,) cannot broadcast, while shape (2,1) and (3,) can, which becomes (2,3).

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.