10

I'd like to sort my numpy array of shape [n,4], along first dimension (size:n) using a custom predicate operating on the 2nd dimension vector (size:4). The C++ version of what I'd like to do is below, it's quite simple really. I've seen how to do this with python lists, but I can't find the syntax to do it with numpy arrays. Is this possible? The documentation on np.sort, np.argsort, np.lexsort doesn't mention custom predicates.

// c++ version
vector< float[4] > v = init_v(); 
float[4] p = init_p();
std::sort(v.begin(), v.end(), [&p](const auto& lhs, const auto& rhs) {
   return myfn(p, lhs) > myfn(p, rhs); });

EDIT: below is the python code I would like to use for the sorting. I.e. for each 'row' (n:4) of my array, I'd calculate the square of the euclidean 3D distance (i.e. only the first 3 columns) to a fixed point.

# these both operate on numpy vectors of shape [4] (i.e. a single row of my data matrix)
def dist_sq(a,b):
    d = a[:3]-b[:3]
    return np.dot(d*d)

def sort_pred(lhs, rhs, p):
    return dist_sq(lhs, p) > dist_sq(rhs, p)

1 Answer 1

17

In numpy you would apply the (vectorized) order defining function to the array, then use np.argsort to sort by the result.

This is less space efficient than the C++ version, but that is how you usually achieve performance with numpy.

import numpy as np    

def myfn(x):
    return np.sin(x[:, 1])  # example: sort by the sine of the second column

a = np.random.randn(10, 4)

predicate = myfn(a)  # not sure if predicate is the best name for this variable
order = np.argsort(predicate)

a_sorted = a[order]
Sign up to request clarification or add additional context in comments.

4 Comments

This is a good approach, but it doesn't handle sorting by multiple keys --- iow, primarily by column A, then secondarily by column B, etc.
@KylePena For that you can use numpy.lexsort instead of numpy.argsort. Either pass the array directly or apply a predicate transformation as in this Q/A.
This doesn't solve the question. @memo wants to order a set of objects only given a function that compares two objects. Argsort works only on objects with some representation as a number.
@JoshAlbert This answered the question before it had been edited. And, apparently, the answer worked for the OP anyway. Feel free to post an alternative answer if you deem this one inadequate.

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.