15

Is there a way to sort the rows of a numpy ndarray using a key (or comparator) function, without resorting to converting to a python list?

In particular, I need to sort according to this function:

c1,c2= 4,7
lambda row: c1*(row[1]/c2)+row[0]

I realise one possible solution would be to generate a vector with the key value of each row, but how would one sort according to it? Should one seek to convert such vector into a index vector somehow?

order= c1*(matrix[:,1]/c2)+matrix[:,0]
indexes= order_to_index( order )
return matrix[ indexes ]

Is this realistic?

4
  • 2
    order_to_index? Do you mean argsort? Commented Oct 13, 2012 at 23:22
  • @wiso indeed! it never occurred to me that this is the same problem as giving the indexes that order the key value vector and sorting by it! Commented Oct 13, 2012 at 23:35
  • just try: np.argsort([3,6,2,2,8]) #-> array([2, 3, 0, 1, 4]). It doesn't sort your original input. Usually numpy functions don't have side effects Commented Oct 13, 2012 at 23:38
  • @wiso indeed, just did, I edited my last post in the meantime, sorry. Thank you! Will you consider adding an answer? Commented Oct 13, 2012 at 23:40

2 Answers 2

7

your approach is right, it is similar to the Schwartzian transform or Decorate-Sort-Undecorate (DSU) idiom

As I said you can use the numpy function np.argsort. It does the work of your order_to_index.

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

Comments

6

For a more explicit answer, suppose we have an array x and want to sort the rows according to some function func which takes a row of x and outputs a scalar.

x[np.apply_along_axis(func, axis=1, arr=x).argsort()]

For this example

c1, c2 = 4, 7
x = np.array([
    [0, 1],
    [2, 3],
    [4, -5]
])
x[np.apply_along_axis(lambda row: c1 * / c2 * row[1] + row[0], 1, x).argsort()]

Out:

array([[ 0,  1],
       [ 4, -5],
       [ 2,  3]])

In this case, np.apply_along_axis isn't even necessary.

x[(c1 / c2 * x[:,1] + x[:,0]).argsort()]

Out:

array([[ 0,  1],
       [ 4, -5],
       [ 2,  3]])

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.