web-dev-qa-db-fra.com

Numpy argsort - que fait-il?

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.

87
user1276273

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.
95
falsetru

[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. 

29
unutbu

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.

2
BrenBarn

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.

0
vivek

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
0
Multihunter

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])

0
JMpony

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

0
Yogesh

Tout d'abord, il a été commandé le tableau. Générez ensuite un tableau avec l'indice initial du tableau.

0
Rodrigo Saraguro