86

I'm trying to sort the rows of one array by the values of another. For example:

import numpy as np
arr1 = np.random.normal(1, 1, 80)
arr2 = np.random.normal(1,1, (80,100))

I want to sort arr1 in descending order, and to have the current relationship between arr1 and arr2 to be maintained (ie, after sorting both, the rows of arr1[0] and arr2[0, :] are the same).

2 Answers 2

134

Use argsort as follows:

arr1inds = arr1.argsort()
sorted_arr1 = arr1[arr1inds[::-1]]
sorted_arr2 = arr2[arr1inds[::-1]]

This example sorts in descending order.

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

5 Comments

Initially this solution was't working with my arrays, but then I realized the len(arr1) has to match the rows of arr2. For example, I had a (5,) vector and a (2, 5) array, which I wanted to sort column-wise by the first vector. I did this using two transposes like arr2.T[arr1.argsort()].T, although there is probably a more elegant solution that doesn't require two transposes.
Are you sure it sorts in descending order? When I try it, it definitely looks like it's ascending: arr = np.array([4, 1, 5, 3, 2]); arr[np.argsort(arr)] gives me the output [1, 2, 3, 4, 5].
@hellobenallan argsort sorts in ascending order, but this solution accesses the indices in reverse order (with [::-1]) to give an answer in descending order.
@ZX9 You're quite right, and your edits make it much more clear what's going on. Thanks for following up.
Potentially useful note: to sort like this along an axis, i.e. if you're using argsort(axis=N), you'll have to use numpy's take_along_axis instead of advanced slicing to sort.
15

Use the zip function: zip( *sorted( zip(arr1, arr2) ) ) This will do what you need.

Now the explanation: zip(arr1, arr2) will combine the two lists, so you've got [(0, [...list 0...]), (1, [...list 1...]), ...] Next we run sorted(...), which by default sorts based on the first field in the tuple. Then we run zip(...) again, which takes the tuples from sorted, and creates two lists, from the first element in the tuple (from arr1) and the second element (from arr2).

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.