Pregunta Numpy argsort - ¿qué está haciendo?


¿Por qué es numpy dando este resultado?

x = numpy.array([1.48,1.41,0.0,0.1])
print x.argsort()

>[2 3 1 0]

cuando esperaba que hiciera esto:

[3 2 0 1]

Claramente mi comprensión de la función es deficiente.


75
2017-07-27 18:44


origen


Respuestas:


De acuerdo a la documentación

Devuelve los índices que ordenarían una matriz.

  • 2 es el índice de 0.0.
  • 3 es el índice de 0.1.
  • 1 es el índice de 1.41.
  • 0 es el índice de 1.48.

80
2017-07-27 18:48



[2, 3, 1, 0] indica que el elemento más pequeño está en el índice 2, el siguiente más pequeño en el índice 3, luego el índice 1, luego el índice 0.

Existen una serie de formas para obtener el resultado que está buscando:

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

Por ejemplo,

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

Esto comprueba que todos producen el mismo resultado:

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

Estos IPython %timeit puntos de referencia sugiere para grandes matrices using_indexed_assignment es el más rápido:

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

Para matrices pequeñas, using_argsort_twice puede ser más rápido:

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

Tenga en cuenta también que stats.rankdata le da más control sobre cómo manejar elementos de igual valor.


26
2017-07-27 18:47



Como la documentación dice, argsort:

Devuelve los índices que ordenarían una matriz.

Eso significa que el primer elemento del argsort es el índice del elemento que debe ordenarse primero, el segundo elemento es el índice del elemento que debe ser el segundo, etc.

Lo que parece querer es el orden jerárquico de los valores, que es lo que proporciona scipy.stats.rankdata. Tenga en cuenta que debe pensar en lo que debería suceder si hay vínculos en los rangos.


2
2017-07-27 18:48



Primero, se ordenó la matriz. Luego genere una matriz con el índice inicial de la matriz.


0
2018-06-27 01:27



Solo quiero contrastar directamente la comprensión original del OP con la implementación real con código.

numpy.argsort se define de tal manera que

x[x.argsort()] == numpy.sort(x) # this will be an array of True's

El OP originalmente pensó que estaba definido de tal manera que

x == numpy.sort(x)[x.argsort()] # this will not be True

0
2017-11-17 07:33



entrada:
    importar numpy como np
    x = np.array ([1.48,1.41,0.0,0.1])
    x.argsort (). argsort ()

salida:
array ([3, 2, 0, 1])


0
2018-02-18 01:50



np.argsort devuelve el índice de la matriz ordenada dada por el 'tipo' (que especifica el tipo de algoritmo de clasificación). Sin embargo, cuando se utiliza una lista con np.argmax, devuelve el índice del elemento más grande de la lista. Mientras, np.sort, ordena la matriz dada, lista.


0
2017-07-22 08:47