Either tell python to sort only on the first item
sorted(ls, key=lambda t: t[0])
Or convert the whole thing to a structured numpy array and ask numpy to sort it
ls_arr = np.array(ls, dtype=[('my_val', float), ('my_arr', float, 2)])
ls_arr.sort()
This second option only works if the arrays are always the same length.
Answer from Eric on Stack OverflowEither tell python to sort only on the first item
sorted(ls, key=lambda t: t[0])
Or convert the whole thing to a structured numpy array and ask numpy to sort it
ls_arr = np.array(ls, dtype=[('my_val', float), ('my_arr', float, 2)])
ls_arr.sort()
This second option only works if the arrays are always the same length.
Probably using the key parameter. Is this what you want?
import numpy as np
ls = [(1.0,np.array([3.0, 4.0])), (1.0,np.array([3.0, 4.1])), (3.0,np.array([2.0, 1.0]))]
ls.sort(key=lambda x: x[0])
Videos
According to the documentation
Returns the indices that would sort an array.
2is the index of0.0.3is the index of0.1.1is the index of1.41.0is the index of1.48.
[2, 3, 1, 0] indicates that the smallest element is at index 2, the next smallest at index 3, then index 1, then index 0.
There are a number of ways to get the result you are looking for:
import numpy as np
import scipy.stats as stats
def using_indexed_assignment(x):
"https://stackoverflow.com/a/5284703/190597 (Sven Marnach)"
result = np.empty(len(x), dtype=int)
temp = x.argsort()
result[temp] = np.arange(len(x))
return result
def using_rankdata(x):
return stats.rankdata(x)-1
def using_argsort_twice(x):
"https://stackoverflow.com/a/6266510/190597 (k.rooijers)"
return np.argsort(np.argsort(x))
def using_digitize(x):
unique_vals, index = np.unique(x, return_inverse=True)
return np.digitize(x, bins=unique_vals) - 1
For example,
In [72]: x = np.array([1.48,1.41,0.0,0.1])
In [73]: using_indexed_assignment(x)
Out[73]: array([3, 2, 0, 1])
This checks that they all produce the same result:
x = np.random.random(10**5)
expected = using_indexed_assignment(x)
for func in (using_argsort_twice, using_digitize, using_rankdata):
assert np.allclose(expected, func(x))
These IPython %timeit benchmarks suggests for large arrays using_indexed_assignment is the fastest:
In [50]: x = np.random.random(10**5)
In [66]: %timeit using_indexed_assignment(x)
100 loops, best of 3: 9.32 ms per loop
In [70]: %timeit using_rankdata(x)
100 loops, best of 3: 10.6 ms per loop
In [56]: %timeit using_argsort_twice(x)
100 loops, best of 3: 16.2 ms per loop
In [59]: %timeit using_digitize(x)
10 loops, best of 3: 27 ms per loop
For small arrays, using_argsort_twice may be faster:
In [78]: x = np.random.random(10**2)
In [81]: %timeit using_argsort_twice(x)
100000 loops, best of 3: 3.45 ยตs per loop
In [79]: %timeit using_indexed_assignment(x)
100000 loops, best of 3: 4.78 ยตs per loop
In [80]: %timeit using_rankdata(x)
100000 loops, best of 3: 19 ยตs per loop
In [82]: %timeit using_digitize(x)
10000 loops, best of 3: 26.2 ยตs per loop
Note also that stats.rankdata gives you more control over how to handle elements of equal value.