Frage Numpy argsort - was macht es?


Warum gibt numpy dieses Ergebnis:

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

>[2 3 1 0]

wann würde ich das erwarten:

[3 2 0 1]

Offensichtlich fehlt mir das Verständnis für die Funktion.


75
2017-07-27 18:44


Ursprung


Antworten:


Gemäß die Dokumentation

Gibt die Indizes zurück, die ein Array sortieren würden.

  • 2 ist der Index von 0.0.
  • 3 ist der Index von 0.1.
  • 1 ist der Index von 1.41.
  • 0 ist der Index von 1.48.

80
2017-07-27 18:48



[2, 3, 1, 0] zeigt an, dass das kleinste Element bei Index 2, das nächstkleinere bei Index 3, dann Index 1 und dann Index 0 ist.

Es gibt eine Reihe von Möglichkeiten um das gesuchte Ergebnis zu erhalten:

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

Beispielsweise,

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

Dies überprüft, ob sie alle das gleiche Ergebnis liefern:

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

Diese IPython %timeit Benchmarks empfehlen sich für große Arrays using_indexed_assignment ist der Schnellste:

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

Für kleine Arrays, using_argsort_twice kann schneller sein:

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

Beachten Sie auch das stats.rankdata gibt Ihnen mehr Kontrolle darüber, wie Sie mit gleichwertigen Elementen umgehen.


26
2017-07-27 18:47



Wie die Dokumentation sagt, argsort:

Gibt die Indizes zurück, die ein Array sortieren würden.

Das heißt, das erste Element des Arguments ist der Index des Elements, das zuerst sortiert werden soll, das zweite Element ist der Index des Elements, das das zweite Element sein soll usw.

Was Sie zu haben scheinen, ist die Rangordnung der Werte, die von scipy.stats.rankdata. Beachten Sie, dass Sie darüber nachdenken müssen, was passieren sollte, wenn in den Rängen Gleichstände vorhanden sind.


2
2017-07-27 18:48



Zuerst wurde das Array bestellt. Dann erzeuge ein Array mit dem Anfangsindex des Arrays.


0
2018-06-27 01:27



Ich möchte nur das ursprüngliche Verständnis des OP gegenüber der tatsächlichen Implementierung mit Code gegenüberstellen.

numpy.argsort ist so definiert, dass

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

Das OP dachte ursprünglich, dass es so definiert wurde, dass

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

0
2017-11-17 07:33



Eingang:
    importiere numpy als np
    x = np.array ([1.48,1,41,0,0,0,1])
    x.argsort (). argsort ()

Ausgabe:
Array ([3, 2, 0, 1])


0
2018-02-18 01:50



np.argsort gibt den Index des sortierten Arrays zurück, der durch die 'art' angegeben wird (die den Typ des Sortieralgorithmus angibt). Wenn jedoch eine Liste mit np.argmax verwendet wird, wird der Index des größten Elements in der Liste zurückgegeben. While, np.sort, sortiert das angegebene Array, list.


0
2017-07-22 08:47