Sort 2D numpy array (by row) based on another 2D array of same shape

Question:

With two arrays:

X = np.array([[1,2,3], [2,3,1]])
X
array([[1, 2, 3],
       [2, 3, 1]])
Y = np.array([['A','B', 'C'], ['A','B', 'C']])
Y
array([['A', 'B', 'C'],
       ['A', 'B', 'C']], 
     dtype='|S1')

I am trying to sort Y based on the values of X row by row without looping through each row, i.e

xord = X.argsort()

for i in range(X.shape[0]):
    print Y[i][xord[i]]

['A' 'B' 'C']
['C' 'A' 'B']

Is there a more efficient way to sort array Y based on the corresponding row order of X?

Asked By: Ryan

||

Answers:

First you can use np.argsort to get the indices of X elements based on those position after sorting,then you can get the elements from Y based on the indices of X with np.take():

>>> s=np.argsort(X)
>>> np.take(Y,s)
array([['A', 'B', 'C'],
       ['C', 'A', 'B']], 
      dtype='|S1')
Answered By: Mazdak

Altering Mazdak’s answer based on AdrianBoeh’s comment, after I found this similar question here How to using numpy.argsort on a 2D array to sort another 2D array :

    X = np.array([[1,2,3], [2,3,1]])
    Y = np.array([['A','B', 'C'],['X','Y','Z']])
    s=np.argsort(X)
    np.take_along_axis(Y,s,axis=1)

It seems that the np.take(Y,s) applies the indexes s only to the first row of Y, so np.take_along_axis is necessary in this kind of problem if the rows of Y are not all the same.

Answered By: user8641371
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.