Pourquoi numpy donne-t-il ce résultat:
x = numpy.array([1.48,1.41,0.0,0.1])
print x.argsort()
>[2 3 1 0]
quand je m'attendrais à ce qu'il fasse ceci:
[3 2 0 1]
De toute évidence, ma compréhension de la fonction fait défaut.
Pourquoi numpy donne-t-il ce résultat:
x = numpy.array([1.48,1.41,0.0,0.1])
print x.argsort()
>[2 3 1 0]
quand je m'attendrais à ce qu'il fasse ceci:
[3 2 0 1]
De toute évidence, ma compréhension de la fonction fait défaut.
Réponses:
Selon la documentation
Renvoie les indices qui trieraient un tableau.
2
est l'indice de 0.0
.3
est l'indice de 0.1
.1
est l'indice de 1.41
.0
est l'indice de 1.48
.a = x.argsort()
, imprimer x[a]
, nous obtiendronsarray([ 0. , 0.1 , 1.41, 1.48])
[2, 3, 1, 0]
indique que le plus petit élément est à l'index 2, le plus petit suivant à l'index 3, puis l'index 1, puis l'index 0.
Il existe plusieurs façons d'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 %timeit
benchmarks IPython suggèrent que pour les grands tableaux, using_indexed_assignment
c'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
Pour les petits tableaux, 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 cela stats.rankdata
vous donne plus de contrôle sur la façon de gérer les éléments de valeur égale.
argsort
retourne les indices du tableau trié. L'index des indices triés est le rang. C'est ce que argsort
retourne le deuxième appel .
Comme la documentation dit argsort
:
Renvoie les indices 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 le deuxième, etc.
Ce que vous semblez vouloir, c'est l'ordre de classement des valeurs, qui est fourni par scipy.stats.rankdata
. Notez que vous devez réfléchir à ce qui devrait se passer s'il y a des liens dans les rangs.
numpy.argsort (a, axis = -1, kind = 'quicksort', order = None)
Renvoie les indices qui trieraient un tableau
Effectuez un tri indirect le long de l'axe donné en utilisant l'algorithme spécifié par le mot-clé kind. Il renvoie 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, ayant 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]
Voici la liste des indices de valeurs dans listExample si vous mappez ces indices 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 ne voulez pas utiliser la fonction list.sort () (c'est-à-dire sans changer l'ordre des valeurs réelles dans la liste), vous pouvez l'utiliser fonction.)
Pour plus de détails, référez-vous à ce lien: https://docs.scipy.org/doc/numpy-1.15.0/reference/generated/numpy.argsort.html
input:
import numpy as np
x = np.array ([1.48,1.41,0.0,0.1])
x.argsort (). argsort ()
sortie:
tableau ([3, 2, 0, 1])
Tout d'abord, il a été commandé le tableau. Générez ensuite un tableau avec l'index initial du tableau.
Je veux juste comparer directement la compréhension originale du PO avec l'implémentation réelle avec du code.
numpy.argsort
est défini de telle sorte que pour les tableaux 1D:
x[x.argsort()] == numpy.sort(x) # this will be an array of True's
L'OP pensait à l'origine qu'il était défini de telle sorte que pour les tableaux 1D:
x == numpy.sort(x)[x.argsort()] # this will not be True
Remarque: ce code ne fonctionne pas dans le cas général (ne fonctionne que pour 1D), cette réponse est purement à des fins d'illustration.
x[x.argsort()]
n'est pas nécessairement le même que np.sort(x)
. En fait, ce n'est même pas nécessairement la même forme. Essayez ceci avec un tableau 2D. Cela ne fonctionne qu'avec des baies 1D.
Il renvoie des indices en fonction des indices de tableau donnés,, [1.48,1.41,0.0,0.1]
c'est-à-dire:
0.0
est le premier élément, dans l'index [2].
0.1
est le deuxième élément, dans l'index [3].
1.41
est le troisième élément, dans l'index [1].
1.48
est le quatrième élément, dans l'index [0]. Production:
[2,3,1,0]
[3 2 0 1]
cela aurait été la bonne réponse?