Betrachten Sie den folgenden Code:
avgDists = np.array([1, 8, 6, 9, 4])
ids = avgDists.argsort()[:n]
Dies gibt mir Indizes der n
kleinsten Elemente. Ist es möglich, dasselbe argsort
in absteigender Reihenfolge zu verwenden, um die Indizes der n
höchsten Elemente zu erhalten?
ids = np.array(avgDists).argsort()[-n:]
?[3, 1, 2]
. Ihre Linie produziert[2, 1, 3]
(wenn n == 3 als Beispiel)ids = np.array(avgDists).argsort()[-n:][::-1]
. Die Sache ist, zu vermeiden, eine Kopie der gesamten Liste zu erstellen, was Sie erhalten, wenn Sie eine-
davor hinzufügen . Nicht relevant für das kleine Beispiel des OP, könnte für größere Fälle sein.np.array(avgDists).argsort()[::-1][:n]
wird es tun. Wenn Sie numpy verwenden möchten, bleiben Sie in numpy. Konvertieren Sie zuerst die Liste in ein Array:avgDist=np.array(avgDists)
dann wird esavgDist.argsort()[::-1][:n}
Antworten:
Wenn Sie ein Array negieren, werden die niedrigsten Elemente zu den höchsten Elementen und umgekehrt. Daher sind die Indizes der
n
höchsten Elemente:Eine andere Möglichkeit, dies zu begründen, besteht, wie in den Kommentaren erwähnt , darin, zu beobachten, dass die großen Elemente im Argsort an letzter Stelle stehen. Sie können also am Ende des Argsorts lesen, um die
n
höchsten Elemente zu finden :Beide Methoden sind zeitliche Komplexität von O (n log n) , da der
argsort
Aufruf hier der dominierende Begriff ist. Der zweite Ansatz hat jedoch einen schönen Vorteil: Er ersetzt eine O (n) -Negation des Arrays durch ein O (1) -Slice. Wenn Sie mit kleinen Arrays in Schleifen arbeiten, können Sie einige Leistungssteigerungen erzielen, wenn Sie diese Negation vermeiden. Wenn Sie mit großen Arrays arbeiten, können Sie Speicherplatz sparen, da durch die Negation eine Kopie des gesamten Arrays erstellt wird.Beachten Sie, dass diese Methoden nicht immer gleichwertige Ergebnisse liefern: Wenn eine stabile Sortierimplementierung angefordert wird
argsort
, z. B. durch Übergeben des Schlüsselwortargumentskind='mergesort'
, behält die erste Strategie die Sortierstabilität bei, die zweite Strategie unterbricht jedoch die Stabilität (dh die Positionen gleich) Artikel werden umgekehrt).Beispielzeiten:
Bei Verwendung einer kleinen Anordnung von 100 Schwimmern und einer Länge von 30 Schwanz war die Ansichtsmethode etwa 15% schneller
Bei größeren Arrays ist der Argsort dominant und es gibt keinen signifikanten Zeitunterschied
Bitte beachten Sie, dass der Kommentar von nedim unten falsch ist. Ob vor oder nach dem Umkehren abgeschnitten werden soll, spielt keine Rolle für die Effizienz, da beide Vorgänge nur eine unterschiedliche Ansicht des Arrays anzeigen und keine Daten tatsächlich kopieren.
quelle
np.array(avgDists).argsort()[:-n][::-1]
Genau wie bei Python
[::-1]
kehrt dies das von zurückgegebene Array umargsort()
und[:n]
gibt die letzten n Elemente an:Der Vorteil dieser Methode ist , dass
ids
a Ansicht von avgDists:(Wenn 'OWNDATA' falsch ist, ist dies eine Ansicht, keine Kopie.)
Ein anderer Weg, dies zu tun, ist so etwas wie:
Das Problem ist, dass dies so funktioniert, dass für jedes Element im Array ein Negativ erstellt wird:
ANd erstellt dazu eine Kopie:
Wenn Sie also jeweils eine Zeit festlegen, mit diesem sehr kleinen Datensatz:
Die Ansichtsmethode ist wesentlich schneller (und verwendet die Hälfte des Speichers ...)
quelle
Sie können die Flip-Befehle verwenden
numpy.flipud()
odernumpy.fliplr()
die Indizes nach dem Sortieren mit demargsort
Befehl in absteigender Reihenfolge abrufen . Das mache ich normalerweise.quelle
Anstatt zu verwenden
np.argsort
, könnten Sie verwendennp.argpartition
- wenn Sie nur die Indizes der niedrigsten / höchsten n Elemente benötigen.Dazu muss nicht das gesamte Array sortiert werden, sondern nur der Teil, den Sie benötigen. Beachten Sie jedoch, dass die "Reihenfolge innerhalb Ihrer Partition" undefiniert ist. Obwohl sie die richtigen Indizes enthält, sind sie möglicherweise nicht richtig geordnet:
quelle
Sie können eine Kopie des Arrays erstellen und dann jedes Element mit -1 multiplizieren.
Infolgedessen würden die vorher größten Elemente die kleinsten werden.
Die Unabhängigkeiten der n kleinsten Elemente in der Kopie sind die n größten Elemente im Original.
quelle
-array
Wie @Kanmani angedeutet hat, kann eine einfacher zu interpretierende Implementierung verwendet werden
numpy.flip
, wie im Folgenden:Durch die Verwendung des Besuchermusters anstelle von Mitgliedsfunktionen ist es einfacher, die Reihenfolge der Vorgänge zu lesen.
quelle
Mit Ihrem Beispiel:
Erhalten Sie Indizes von n Maximalwerten:
Sortieren Sie sie in absteigender Reihenfolge:
Ergebnisse erhalten (für n = 4):
quelle
Eine andere Möglichkeit besteht darin, im Argument für argsort nur ein '-' zu verwenden, wie in: "df [np.argsort (-df [:, 0])]", vorausgesetzt, df ist der Datenrahmen und Sie möchten ihn nach dem ersten sortieren Spalte (dargestellt durch die Spaltennummer '0'). Ändern Sie den Spaltennamen entsprechend. Natürlich muss die Spalte eine numerische sein.
quelle