Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to sort a list based on the output of numpy's argsort function

I have a list like this:

 myList = [10,30,40,20,50]

Now I use numpy's argsort function to get the indices for the sorted list:

import numpy as np
so = np.argsort(myList)

which gives me the output:

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

When I want to sort an array using so it works fine:

myArray = np.array([1,2,3,4,5])
myArray[so]
array([1, 4, 2, 3, 5])

But when I apply it to another list, it does not work but throws an error

myList2 = [1,2,3,4,5]
myList2[so]

TypeError: only integer arrays with one element can be converted to an index

How can I now use so to sort another list without using a for-loop and without converting this list to an array first?

like image 315
Cleb Avatar asked Oct 29 '25 12:10

Cleb


2 Answers

myList2 is a normal python list, and it does not support that kind of indexing.

You would either need to convert that to a numpy.array , Example -

In [8]: np.array(myList2)[so]
Out[8]: array([1, 4, 2, 3, 5])

Or you can use list comprehension -

In [7]: [myList2[i] for i in so]
Out[7]: [1, 4, 2, 3, 5]
like image 194
Anand S Kumar Avatar answered Oct 31 '25 02:10

Anand S Kumar


You can't. You have to convert it to an array then back.

myListSorted = list(np.array(myList)[so])

Edit: I ran some benchmarks comparing the NumPy way to the list comprehension. NumPy is ~27x faster

>>> from timeit import timeit
>>> import numpy as np

>>> myList = list(np.random.rand(100))
>>> so = np.argsort(myList) #converts list to NumPy internally
>>> timeit(lambda: [myList[i] for i in so])
12.29590070003178

>>> myArray = np.random.rand(100)
>>> so = np.argsort(myArray)
>>> timeit(lambda: myArray[so]) 
0.42915570305194706
like image 24
rohanp Avatar answered Oct 31 '25 00:10

rohanp



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!