1

I have the following code/data:

import numpy as np

data = np.array([
    [12, 1, 0.7, 0],
    [13, 2, 0.5, 1],
    [41, 3, 0.3, 0],
    [20, 2, 0.8, 0],
    [51, 2, 0.7, 0],
    [32, 0, 0.9, 0],
    [17, 4, 0.7, 1],
    [54, 1, 0.6, 1],
    [22, 1, 0.4, 1],
    [74, 0, 0.5, 0],
    [11, 4, 0.3, 1],
    [13, 3, 0.8, 0],
    [15, 4, 0.3, 0],
    [65, 3, 0.2, 1],
])

I want to sort the 2d array: mainly by data[:, 1] in acending order (from lowest to highest) and secondly, data[:, 2] in decending order (highest to lowest) so I've come up with the following code:

data[:, 2] = -data[:, 2]
ind = np.lexsort((data[:, 2], data[:, 1]))
data[:, 2] = -data[:, 2]
data = data[ind]
print data

which have resulted:

[[ 32.    0.    0.9   0. ]
 [ 74.    0.    0.5   0. ]
 [ 12.    1.    0.7   0. ]
 [ 54.    1.    0.6   1. ]
 [ 22.    1.    0.4   1. ]
 [ 20.    2.    0.8   0. ]
 [ 51.    2.    0.7   0. ]
 [ 13.    2.    0.5   1. ]
 [ 13.    3.    0.8   0. ]
 [ 41.    3.    0.3   0. ]
 [ 65.    3.    0.2   1. ]
 [ 17.    4.    0.7   1. ]
 [ 11.    4.    0.3   1. ]
 [ 15.    4.    0.3   0. ]]

Its correct. But I would like to know if theres a better way to do it. first if it is possible to do it in a shorter run-time. second, a more simple pytonic code.

to make it even shorter (and more pythonic) I can do this:

ind = np.lexsort((-data[:, 2], data[:, 1]))
data = data[ind]

Run-time still remains unanswered.

Eran Moshe
  • 3,062
  • 2
  • 22
  • 41
  • [This](http://stackoverflow.com/questions/6835531/sorting-a-python-array-recarray-by-column) might be helpful. – Eli Sadoff Nov 07 '16 at 19:12

1 Answers1

2

You could directly use the negated second column with np.lexsort -

data[np.lexsort((-data[:, 2], data[:, 1]))]

Assuming non-negative integer values in first column and non-negative values in second column, here's an alternative with argsort -

data[(data[:,1]*(data[:,2].max()+1) - data[:,2]).argsort()]

If the second column always have elements in [0,1), we could simply a bit -

data[(data[:,1] - data[:,2]).argsort()]
Divakar
  • 218,885
  • 19
  • 262
  • 358