web-dev-qa-db-fra.com

Équivalent de Numpy.argsort () en python basique?

existe-t-il une fonction intégrée de Python qui fait sur python.array ce que argsort() fait sur un numpy.array?

54
Mermoz

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

53
Boris Gorelik

Il n'y a pas de fonction intégrée, mais il est facile d'en assembler un parmi les formidables outils Python met à 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.arrays de la même manière:

import array
x = array.array('d', [5, 2, 1, 10])
print(argsort(x))
# [2, 1, 0, 3]
64
unutbu

Mon alternative avec énumérer:

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 vaut utiliser la réponse de https://stackoverflow.com/users/9990/marcelo-cantos réponse au thread tri en python sans expressions lambda

[i for (v, i) in sorted((v, i) for (i, v) in enumerate(seq))]
5
Tony Veijalainen

Trouvé cette question, mais avait besoin d'argsort pour une liste d'objets basée sur une propriété d'objet.

Étendre la réponse d'unutbu, ce serait:

sorted(range(len(seq)), key = lambda x: seq[x].sort_property)
2
Jeff M.