Pourquoi numpy donne ce résultat:
x = numpy.array([1.48,1.41,0.0,0.1])
print x.argsort()
>[2 3 1 0]
quand je m'attendais à ce qu'il fasse ceci:
[3 2 0 1]
Il est clair que ma compréhension de la fonction manque.
Selon la documentation
Retourne les index qui trieraient un tableau.
2
est l'index de 0.0
.3
est l'index de 0.1
.1
est l'index de 1.41
.0
est l'index de 1.48
.[2, 3, 1, 0]
indique que le plus petit élément est à l'index 2, le deuxième plus petit à l'index 3, puis à l'index 1, puis à l'index 0.
Il y a un certain nombre de façons pour obtenir le résultat que vous recherchez:
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
Par exemple,
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])
Cela vérifie qu'ils produisent tous le même résultat:
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))
Ces repères IPython %timeit
suggèrent que, pour les tableaux de grande taille, using_indexed_assignment
est le plus rapide:
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
using_argsort_twice
peut être plus rapide:
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
Notez également que stats.rankdata
vous donne plus de contrôle sur la manière de traiter les éléments de valeur égale.
Comme la documentation dit, argsort
:
Retourne les index qui trieraient un tableau.
Cela signifie que le premier élément de argsort est l'index de l'élément qui doit être trié en premier, le deuxième élément est l'index de l'élément qui devrait être deuxième, etc.
Ce que vous semblez vouloir, c’est le classement des valeurs, qui est fourni par scipy.stats.rankdata
. Notez que vous devez penser à ce qui devrait se passer s'il y a des liens dans les rangs.
np.argsort renvoie l'index du tableau trié donné par le "kind" (qui spécifie le type d'algorithme de tri). Cependant, lorsqu'une liste est utilisée avec np.argmax, elle retourne l'index du plus grand élément de la liste. Alors que, np.sort, trie le tableau donné, liste.
Je veux juste opposer directement la compréhension initiale du PO à la mise en œuvre réelle avec du code.
numpy.argsort
est défini de telle sorte que
x[x.argsort()] == numpy.sort(x) # this will be an array of True's
Le PO pensait à l'origine qu'il était défini de manière à
x == numpy.sort(x)[x.argsort()] # this will not be True
contribution:
importer numpy en tant que np
x = np.array ([1.48,1.41,0,0,0,0.1])
x.argsort (). argsort ()
sortie:
array ([3, 2, 0, 1])
numpy.argsort (a, axis = -1, kind = 'quicksort', order = None)
Retourne les index qui trieraient un tableau
Effectuez un tri indirect le long de l'axe donné à l'aide de l'algorithme spécifié par le mot-clé kind. Il retourne un tableau d'indices de la même forme que ces données d'index le long de l'axe donné, dans l'ordre trié.
Prenons un exemple en python, avec une liste de valeurs comme
listExample = [0 , 2, 2456, 2000, 5000, 0, 1]
Maintenant, nous utilisons la fonction argsort:
import numpy as np
list(np.argsort(listExample))
La sortie sera
[0, 5, 6, 1, 3, 2, 4]
Ceci est la liste des indices de valeurs dans listExample si vous mappez ces index aux valeurs respectives, nous obtiendrons le résultat comme suit:
[0, 0, 1, 2, 2000, 2456, 5000]
(Je trouve cette fonction très utile dans de nombreux endroits, par exemple si vous voulez trier la liste/le tableau mais que vous ne voulez pas utiliser la fonction list.sort () une fonction.)
Pour plus de détails, consultez ce lien: https://docs.scipy.org/doc/numpy-1.15.0/reference/generated/numpy.argsort.html
Tout d'abord, il a été commandé le tableau. Générez ensuite un tableau avec l'indice initial du tableau.