Y at-il une fonction intégrée de Python qui fait sur python.array
ce que fait argsort()
sur un numpy.array
?Equivalent de Numpy.argsort() en python de base?
Répondre
J'ai chronométré les suggestions ci-dessus et voici mes résultats.
Tout d'abord, les fonctions:
def f(seq):
# http://stackoverflow.com/questions/3382352/equivalent-of-numpy-argsort-in-basic-python/3383106#3383106
#non-lambda version by Tony Veijalainen
return [i for (v, i) in sorted((v, i) for (i, v) in enumerate(seq))]
def g(seq):
# http://stackoverflow.com/questions/3382352/equivalent-of-numpy-argsort-in-basic-python/3383106#3383106
#lambda version by Tony Veijalainen
return [x for x,y in sorted(enumerate(seq), key = lambda x: x[1])]
def h(seq):
#http://stackoverflow.com/questions/3382352/equivalent-of-numpy-argsort-in-basic-python/3382369#3382369
#by unutbu
return sorted(range(len(seq)), key=seq.__getitem__)
Maintenant, la session IPython:
In [16]: seq = rand(10000).tolist()
In [17]: %timeit f(seq)
100 loops, best of 3: 10.5 ms per loop
In [18]: %timeit g(seq)
100 loops, best of 3: 8.83 ms per loop
In [19]: %timeit h(seq)
100 loops, best of 3: 6.44 ms per loop
FWIW
Il n'y a aucune fonction intégrée, mais il est facile d'assembler un sur des outils formidables Python met à la disposition:
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]
Il fonctionne sur Python array.array
de la même façon:
import array
x = array.array('d', [5, 2, 1, 10])
print(argsort(x))
# [2, 1, 0, 3]
+1 Très Pythonic! – katrielalex
Au lieu d'utiliser le __getitem__ (théoriquement privé), vous pouvez également utiliser 'operator.itemgetter' /' operator.attrgetter' http://docs.python.org/library/operator.html – Ender
Si 'operator.itemgetter' peut être Utilisé comme remplacement de '__getitem__', je pense que j'étais d'accord avec toi Ender, mais pour autant que je puisse voir,' operator.itemgetter' nécessiterait aussi de l'entourer d'une expression 'lambda'. Je préférerais éviter le «lambda» supplémentaire si je le pouvais. – unutbu
Mon autre avec 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]
mieux que d'utiliser de réponse https://stackoverflow.com/users/9990/marcelo-cantos répondre à enfiler python sort without lambda expressions
[i for (v, i) in sorted((v, i) for (i, v) in enumerate(seq))]
Trouvé cette question, mais nécessaire argsort pour une liste des objets en fonction de une propriété d'objet.
L'extension de la réponse de unutbu, ce serait:
sorted(range(len(seq)), key = lambda x: seq[x].sort_property)
Intéressant - probablement la moyenne est plus importante que le «meilleur» de 3 (?) – JPH
La moyenne est affectée par les valeurs aberrantes Vous ne voulez pas que les résultats soient pollués par d'autres programmes en cours d'exécution les événements. –