Warum gibt numpy dieses Ergebnis:
x = numpy.array([1.48,1.41,0.0,0.1])
print x.argsort()
>[2 3 1 0]
wenn ich das erwarten würde:
[3 2 0 1]
Offensichtlich fehlt mein Verständnis der Funktion.
Warum gibt numpy dieses Ergebnis:
x = numpy.array([1.48,1.41,0.0,0.1])
print x.argsort()
>[2 3 1 0]
wenn ich das erwarten würde:
[3 2 0 1]
Offensichtlich fehlt mein Verständnis der Funktion.
Antworten:
Laut 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
.a = x.argsort()
, drucken x[a]
, wir werden bekommenarray([ 0. , 0.1 , 1.41, 1.48])
[2, 3, 1, 0]
gibt an, dass sich das kleinste Element bei Index 2 befindet, das nächstkleinere bei Index 3, dann Index 1 und dann Index 0.
Es gibt verschiedene Möglichkeiten , um das gewünschte Ergebnis zu erzielen:
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])
Dadurch wird überprüft, ob alle das gleiche Ergebnis erzielen:
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 legen nahe, dass große Arrays using_indexed_assignment
am schnellsten sind:
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
Bei kleinen Arrays using_argsort_twice
kann dies 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, dass stats.rankdata
Sie mehr Kontrolle darüber haben, wie Sie mit gleichwertigen Elementen umgehen.
argsort
die Indizes des sortierten Arrays zurück. Der Index der sortierten Indizes ist der Rang. Dies ist, was der zweite Aufruf argsort
zurückgibt.
Wie die Dokumentation sagt argsort
:
Gibt die Indizes zurück, die ein Array sortieren würden.
Das heißt, das erste Element der Argsortierung ist der Index des Elements, das zuerst sortiert werden soll, das zweite Element ist der Index des Elements, das an zweiter Stelle stehen soll usw.
Was Sie zu wollen scheinen, ist die Rangfolge der Werte, die von bereitgestellt wird scipy.stats.rankdata
. Beachten Sie, dass Sie darüber nachdenken müssen, was passieren soll, wenn es Bindungen in den Reihen gibt.
numpy.argsort (a, Achse = -1, Art = 'Quicksort', Reihenfolge = Keine)
Gibt die Indizes zurück, die ein Array sortieren würden
Führen Sie eine indirekte Sortierung entlang der angegebenen Achse mit dem durch das Schlüsselwort kind angegebenen Algorithmus durch. Es gibt ein Array von Indizes mit derselben Form wie diese Indexdaten entlang der angegebenen Achse in sortierter Reihenfolge zurück.
Betrachten Sie ein Beispiel in Python mit einer Liste von Werten als
listExample = [0 , 2, 2456, 2000, 5000, 0, 1]
Jetzt verwenden wir die Argsort-Funktion:
import numpy as np
list(np.argsort(listExample))
Die Ausgabe wird sein
[0, 5, 6, 1, 3, 2, 4]
Dies ist die Liste der Werteindizes in listBeispiel Wenn Sie diese Indizes den jeweiligen Werten zuordnen, erhalten wir das Ergebnis wie folgt:
[0, 0, 1, 2, 2000, 2456, 5000]
(Ich finde diese Funktion an vielen Stellen sehr nützlich, z. B. Wenn Sie die Liste / das Array sortieren möchten, aber die Funktion list.sort () nicht verwenden möchten (dh ohne die Reihenfolge der tatsächlichen Werte in der Liste zu ändern), können Sie diese verwenden Funktion.)
Weitere Informationen finden Sie unter folgendem Link: https://docs.scipy.org/doc/numpy-1.15.0/reference/generated/numpy.argsort.html
Eingabe:
importiere numpy als np
x = np.array ([1.48,1.41,0.0,0.1])
x.argsort (). argsort ()
Ausgabe:
Array ([3, 2, 0, 1])
Zuerst wurde das Array bestellt. Generieren Sie dann ein Array mit dem Anfangsindex des Arrays.
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. Während np.sort das angegebene Array sortiert, listet es auf.
Ich möchte nur das ursprüngliche Verständnis des OP direkt mit der tatsächlichen Implementierung mit Code vergleichen.
numpy.argsort
ist so definiert, dass für 1D-Arrays:
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 für 1D-Arrays:
x == numpy.sort(x)[x.argsort()] # this will not be True
Hinweis: Dieser Code funktioniert im allgemeinen Fall nicht (funktioniert nur für 1D). Diese Antwort dient nur zur Veranschaulichung.
x[x.argsort()]
ist nicht unbedingt das gleiche wie np.sort(x)
. In der Tat ist es nicht unbedingt die gleiche Form. Versuchen Sie dies mit einem 2D-Array. Dies funktioniert nur mit 1D-Arrays.
[3 2 0 1]
wäre die richtige Antwort gewesen?