hi is there a build'in function of python that does on python.array what argsort() does on a numpy.array?
+11
A:
There is no built-in function, but it's easy to assemble one out of the terrific tools Python makes available:
def argsort(seq):
# http://stackoverflow.com/questions/3071415/efficient-method-to-calculate-the-rank-vector-of-a-list-in-python
return sorted(range(len(seq)), key=seq.__getitem__)
x=[5,2,1,10]
print(argsort(x))
# [2, 1, 0, 3]
It works on Python array.array
s the same way:
import array
x=array.array('d', [5, 2, 1, 10])
print(argsort(x))
# [2, 1, 0, 3]
unutbu
2010-08-01 14:30:03
+1 Very Pythonic!
katrielalex
2010-08-01 15:07:25
Instead of using the (theoretically private) __getitem__, you can also use `operator.itemgetter` / `operator.attrgetter` http://docs.python.org/library/operator.html
Ender
2010-08-01 17:58:46
If `operator.itemgetter` could be used as a drop-in replacement for `__getitem__`, I think I'd agreed with you Ender, but as far as I can see, `operator.itemgetter` would also require wrapping it in a `lambda` expression. I'd rather avoid the extra `lambda` if I could.
unutbu
2010-08-01 19:57:25
A:
My alternative with enumerate:
def argsort(seq):
return [x for x,y in sorted(enumerate(seq), key = lambda x: x[1])]
seq=[5,2,1,10]
print(argsort(seq))
# Output:
# [2, 1, 0, 3]
Better though to use answer from http://stackoverflow.com/users/9990/marcelo-cantos answer to thread http://stackoverflow.com/questions/3407414/python-sort-without-lambda-expressions
[i for (v, i) in sorted((v, i) for (i, v) in enumerate(seq))]
Tony Veijalainen
2010-08-01 17:53:57