1

I'm having a bit of a difficulty. I'm trying to vectorize some code in python in order to make it faster. I have an array which I sort (A) and get the index list (Ind). I have another array (B) which I would like to sort by the index list, without using loops which I think bottlenecks the computation.

A = array([[2, 1, 9],
           [1, 1, 5],
           [7, 4, 1]])
Ind = np.argsort(A)

This is the result of Ind:

Ind = array([[1, 0, 2],
             [0, 1, 2],
             [2, 1, 0]], dtype=int64)

B is the array i would like to sort by Ind:

B = array([[ 6,  3,  9],
           [ 1,  5,  3],
           [ 2,  7, 13]])

I would like to use Ind to rearrange my elements in B as such (B rows sorted by A rows indexes):

B = array([[ 3,  6,  9],
           [ 1,  5,  3],
           [13,  7,  2]])

Any Ideas? I would be glad to get any good suggestion. I want to mention I am using millions of values, I mean arrays of 30000*5000.

Cheers, Robert

4
  • you are creating Ind and then immediately overwriting it on the next line, just FYI. Commented Mar 11, 2015 at 12:09
  • i just wanted to show the result of Ind . Commented Mar 11, 2015 at 12:11
  • I don't know... use comments or smth; it's confusing when you're obviously overwriting something you just created; also while we're at it, check out python.org/dev/peps/pep-0008 — you might find it useful in the long term. Commented Mar 11, 2015 at 12:12
  • I would have overwritten it with the same values as the results...im not here to pick a fight im here to solve a problem...i appretiate the comments and thanks for the heads up Commented Mar 11, 2015 at 12:17

1 Answer 1

1

I would do something like this:

import numpy as np
from numpy import array

A = array([[2, 1, 9],
           [1, 1, 5],
           [7, 4, 1]])
Ind = np.argsort(A)

B = array([[ 3,  6,  9],
           [ 1,  5,  3],
           [13,  7,  2]])

# an array of the same shape as A and B with row numbers for each element
rownums = np.tile(np.arange(3), (3, 1)).T

new_B = np.take(B, rownums * 3 + Ind)
print(new_B)
# [[ 6  3  9]
#  [ 1  5  3]
#  [ 2  7 13]]

You can replace the magic number 3 with the array shape.

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

2 Comments

You can use broadcasting instead of np.tile in order to get the row indices: rownums = np.arange(3); B[rownums[:, None], Ind]
Good point, it'll be useful if the arrays are huge. And your way of indexing looks clearer than mine.

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.