Wie bekomme ich die Indizes der N maximale Werte in ein NumPy-array?
NumPy schlägt vor, eine Möglichkeit, um den index der maximale Wert eines array über np.argmax
.
Möchte ich eine ähnliche Sache, aber wieder werden die Indizes der N
maximale Werte.
Wenn ich beispielsweise ein array, [1, 3, 2, 4, 5]
, function(array, n=3)
zurückkehren würde, die Indizes [4, 3, 1]
entsprechen die Elemente [5, 4, 3]
.
- möglich, Duplikat der python+numpy: effiziente Weg, um die min/max-n-Werte und Indizes, die aus einer matrix
- Ihre Frage ist nicht wirklich gut definiert. Zum Beispiel, was würden die Indizes (erwartet) werden für
array([5, 1, 5, 5, 2, 3, 2, 4, 1, 5])
-, Pfingst -n= 3
? Was man von all den alternativen, wie[0, 2, 3]
,[0, 2, 9]
,...
wäre die richtige? Bitte erläutern Sie mehr über Ihre spezifischen Anforderungen. Dank - Ich weiß nicht wirklich, über was soll zurückgegeben werden, in diesem speziellen Fall. Auch wenn es logisch erscheinen, geben Sie die ersten begegnete, das ist keine Voraussetzung für mich.
argsort
könnte eine sinnvolle alternative sein, wenn Sie kümmern sich nicht um die Reihenfolge der zurückgegebenen indeces. Siehe meine Antwort unten.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Die einfachste hab ich in der Lage zu kommen mit ist:
Diese beinhaltet eine vollständige Sortierung des Arrays. Ich Frage mich, ob
numpy
bietet eine integrierte Möglichkeit, um eine partielle Sortieren; so weit ich habe nicht in der Lage, einen zu finden.Wenn diese Lösung erweist sich als zu langsam (vor allem für kleine
n
), kann es sein, lohnt ein Blick auf die Codierung etwas in Cython.arr.argsort()[-1:-4:-1]
? Ich habe versucht, es in der Dolmetscher-und es kommt mit dem gleichen Ergebnis, aber ich Frage mich, ob es nicht gebrochen durch einige Beispiel.np.argsort(-arr)[:3]
finde ich besser lesbar und auf den Punkt.:
nicht bezogen auf die Dimensionen richtig? der gesamte Ausdruck verwendet, erstellen Sie eine umgekehrte array? Verstehe ich das richtig?arr.argsort()[::-1][:n]
ist besser, da gibt es leer fürn=0
statt die ganze Paletteargpartition
die isolieren den top-K-Elemente aus der Ruhe, ohne dabei eine vollständige Sortieren, und dann die Sortierung kann nur durchgeführt werden, auf derer K.Neuere NumPy-Versionen (1.8 und höher) haben eine Funktion namens
argpartition
für diese. Um die Indizes der vier größten elementsIm Gegensatz zu
argsort
diese Funktion führt in die lineare Zeit im schlechtesten Fall, aber die zurückgegebenen Indizes sind nicht sortiert, wie kann man aus dem Ergebnis der Auswertunga[ind]
. Wenn Sie brauchen, dass auch die Art, die Sie danach:Zu Holen Sie sich die top-k Elemente in sortierter Reihenfolge in dieser Weise in O(n + k log k) Zeit.
np.argpartition
und seine Schwester Algorithmusnp.partition
Arbeit gibt es eine detaillierte Erklärung in der verlinkten Frage: stackoverflow.com/questions/10337533/...{import numpy as np a = [9, 4, 4, 3, 3, 9, 0, 4, 6, 0] ind = np.argpartition(a, -4)[-4:] a[ind]}
wirft nun dieser Fehler.Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: only integer scalar arrays can be converted to a scalar index
a=np.array([9, 4, 4, 3, 3, 9, 0, 4, 6, 0])
da die normale python-Listen unterstützen keine Indizierung von Listen, im Gegensatz zunp.array
axis
argument. Zu finden sind die indices der top-n-Werte für jede Zeile:np.argpartition(a, -n, axis=1)[-n:]
Einfacher noch:
wo n wird die maximale Anzahl der Werte.
arr[arr.argsort()[-n:]]
statt negieren das array, nur ein Stück von den letzten n ElementeVerwenden:
Zur regelmäßigen Python-Listen:
Wenn Sie die Verwendung von Python 2 verwenden Sie
xrange
stattrange
.Quelle: heapq — Heap-queue-Algorithmus
heapq.nlargest(3, xrange(len(a)), a.take)
. Für Python-Listen, die wir benutzen können.__getitem__
statt.take
.A
im Allgemeinen:heapq.nlargest(3, range(len(A.ravel())), A.ravel().take)
. (Ich hoffe, das funktioniert nur für Ansichten, siehe auch (ravel vs flatten
](stackoverflow.com/a/28930580/603003)).Wenn Sie passieren, mit zu arbeiten, ein mehrdimensionales array, dann werden Sie brauchen, um zu glätten und zu entwirren, die Indizes:
Beispiel:
Wenn Sie kümmern sich nicht um die um des K-TEN größten Elemente, die Sie verwenden können,
argpartition
, das sollte eine bessere Leistung als ein full-Sortieren durchargsort
.Credits gehen an diese Frage.
Ich lief ein paar tests und es sieht aus wie
argpartition
übertrifftargsort
als die Größe des Arrays und der Wert von K erhöht.Für mehrdimensionale arrays können Sie die
axis
Schlüsselwort, um die Aufteilung entlang der vorgegebenen Achse.Und für die Aufbereitung der Elemente:
Aber beachten Sie, dass dies nicht return ein sortiertes Ergebnis. In diesem Fall können Sie
np.argsort()
entlang der soll-Achse:Hier ist ein Beispiel:
Diese schneller als eine volle Art, je nach der Größe Ihrer original-array und die Größe der Auswahl:
Es natürlich, dass die Manipulation mit Ihrem original-array. Das könnte man beheben (falls erforderlich), indem Sie eine Kopie oder ersetzen wieder die ursprünglichen Werte. ...je nachdem, was billiger ist für Ihren Anwendungsfall.
argmax(.)
eindeutig sein, wie gut. (Es IMHO versucht zu Folgen, irgendeine Art von Kurzschluss-Logik, aber leider nicht allgemein akzeptabel Verhalten). DankMethode
np.argpartition
gibt nur die k größten Indizes, führt eine lokale Art, und ist schneller alsnp.argsort
(Durchführung einer vollständigen Art) beim array ist sehr groß. Aber die zurückgegebenen Indizes sind NICHT in aufsteigender/absteigender Reihenfolge. Sagen wir mal mit einem Beispiel:Können wir sehen, dass, wenn Sie möchten, eine strenge aufsteigend top-k Indizes,
np.argpartition
nichts zurückgeben, was Sie wollen.Abgesehen von einer Sortierung manuell nach np.argpartition, meine Lösung ist die Verwendung PyTorch,
Fackel.topk
, ein Werkzeug für neuronale Netzwerk-Konstruktion, die NumPy-wie APIs mit beiden CPU-und GPU-Unterstützung. Es ist so schnell wie NumPy mit MKL, und bietet einen GPU-boost, wenn Sie große matrix-Vektor-Berechnungen.Strengen Aufstieg/Abstieg-top-k Indizes-code:
Beachten Sie, dass
Fackel.topk
nimmt eine Fackel-tensor, und gibt die beiden top-k-Werte und die top-k Indizes in der Arttorch.Tensor
. Ähnliche mit np, Fackel.topk akzeptiert auch eine Achse argument, so dass Sie verarbeiten kann multi-dimensionale arrays/Tensoren.Engpass
hat eine partielle Funktion Sortieren, wenn die Kosten der Sortierung der gesamten Arrays nur die N größten Werte ist zu groß.ich weiß nichts über dieses Modul; ich habe gerade gegoogelt
numpy partial sort
.Verwenden:
Nun die
result
Liste enthalten würde N Tupel (index
,value
), wovalue
maximiert ist.Verwenden:
Es funktioniert auch mit 2D-arrays. Zum Beispiel,
Folgende ist eine sehr einfache Möglichkeit, um zu sehen, das maximum der Elemente und Ihre Positionen. Hier
axis
ist die domain;axis
= 0 bedeutet, dass die Spalte weisen maximale Anzahl undaxis
= 1 bedeutet row-wise max Anzahl für den 2D-Fall. Und für die höheren Dimensionen, es hängt von Euch ab.Ich fand es die meisten intuitiv zu bedienen
np.unique
.Die Idee ist, dass der einheitliche Methode gibt die Indizes der input-Werte. Dann von der max einzigartigen Wert und die Indizes, die die Lage der ursprünglichen Werte wiederhergestellt werden können.
Ich denke, die meisten, Zeit, Effizienz Weg ist, manuell das array Durchlaufen und halten Sie einen k-Größe min-heap, wie andere Leute erwähnt haben.
Und ich komme auch mit einer brute-force-Ansatz:
Gesetzt, das größte element zu einem großen negativen Wert, nachdem Sie argmax um seinen index. Und dann das nächste call of argmax zurück, die zweite größte element.
Und Sie können sich der ursprüngliche Wert dieser Elemente haben, und diese wiederherstellen, wenn Sie wollen.