2

First let's put that out of the way: I'm already aware of the solution discussed here: Create NumPy array from another array by specifying rows and columns

Let's say I have an array

test = np.arange(12).reshape((3,4))

array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

and I want to rearrange its rows and columns into test2

array([[ 1,  0,  3,  2],
       [ 9,  8, 11, 10],
       [ 5,  4,  7,  6]])

The solution I'm using right now is the same as the one already answered in the link above:

test2 = test[[0,2,1]][:,[1,0,3,2]]

However this solution creates an unnecessary intermediate copy of the data: it first creates a copy with shuffled rows only test[[0,2,1]], then creates a second copy with shuffled columns as well. For such a small array, no one cares but if the array is gigantic this solution feels sub-optimal. Does numpy allow rows and columns shuffling simultaneously? Something looking like test[[0,2,1],[1,0,3,2]], except numpy doesn't interpret this operation that way...

0

1 Answer 1

5

Yes, that's the purpose of np.ix_:

>>> test[np.ix_([0,2,1], [1,0,3,2])]
array([[ 1,  0,  3,  2],
       [ 9,  8, 11, 10],
       [ 5,  4,  7,  6]])

It will still create an intermediate index array from the two input arrays but it won't index the test array twice.

Note that np.ix_ just adds dimensions to your index arrays, these will be "broadcasted" when you index the array:

>>> np.ix_([0,2,1], [1,0,3,2])
(array([[0],
        [2],
        [1]]), array([[1, 0, 3, 2]]))
Sign up to request clarification or add additional context in comments.

5 Comments

This solution seems twice slower than my current one...
Actually it's (only) marginally faster when tested on bigger arrays.
Yes, the break even seems to be high. However with 1kk items it's already significantly faster (2 times on my computer).
Well I was hoping for better, but apparently that's as good as numpy allows...
It made a huuuuge difference reordering a 70k x 70k boolean array a: 209.20s and 35.14s for a[idxs][:, idxs] and a[np.ix_(idxs, idxs) respectively

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.