Wie kann ich ein Array in NumPy nach der n-ten Spalte sortieren?
Zum Beispiel,
a = array([[9, 2, 3],
[4, 5, 6],
[7, 0, 5]])
Ich möchte Zeilen nach der zweiten Spalte sortieren, damit ich zurückkomme:
array([[7, 0, 5],
[9, 2, 3],
[4, 5, 6]])
np.sort(a, axis=0)
dies eine zufriedenstellende Lösung für die gegebene Matrix wäre. Ich schlug eine Bearbeitung mit einem besseren Beispiel vor, wurde aber abgelehnt, obwohl die Frage tatsächlich viel klarer wäre. Das Beispiel sollte so etwas wiea = numpy.array([[1, 2, 3], [6, 5, 2], [3, 1, 1]])
mit der gewünschten Ausgabe seinarray([[3, 1, 1], [1, 2, 3], [6, 5, 2]])
Antworten:
@steve 's ist eigentlich die eleganteste Art, es zu tun.
Die "richtige" Methode finden Sie im order-Schlüsselwortargument von numpy.ndarray.sort
Sie müssen Ihr Array jedoch als Array mit Feldern (ein strukturiertes Array) anzeigen.
Der "richtige" Weg ist ziemlich hässlich, wenn Sie Ihr Array ursprünglich nicht mit Feldern definiert haben ...
Als kurzes Beispiel, um es zu sortieren und eine Kopie zurückzugeben:
So sortieren Sie es an Ort und Stelle:
@ Steve's ist wirklich der eleganteste Weg, soweit ich weiß ...
Der einzige Vorteil dieser Methode besteht darin, dass das Argument "order" eine Liste der Felder ist, nach denen die Suche sortiert werden soll. Sie können beispielsweise nach der zweiten Spalte, dann nach der dritten Spalte und dann nach der ersten Spalte sortieren, indem Sie order = ['f1', 'f2', 'f0'] angeben.
quelle
ValueError: new type not compatible with array.
float
? Soll ich etwas ändern?a = np.array([['a',1,2,3],['b',4,5,6],['c',0,0,1]])
welchen Ansatz sollte ich folgen?np.argsort
möglicherweise selbst ziemlich viel Speicher. Darüber hinaus generiert die Indizierung mit einem Array auch eine Kopie des Arrays, das sortiert wird.Ich nehme an, das funktioniert:
a[a[:,1].argsort()]
Dies zeigt die zweite Spalte von an
a
und sortiert sie entsprechend danach.quelle
1
hier drin? der Index, nach dem sortiert werden soll?[:,1]
gibt die zweite Spalte von ana
.a[a[:,1].argsort()[::-1]]
np.sort
oder nicht?ind = np.argsort( a[:,1] ); a = a[ind]
Sie können nach Steve Tjoas Methode nach mehreren Spalten sortieren, indem Sie eine stabile Sortierung wie Mergesort verwenden und die Indizes von den niedrigstwertigen zu den höchstwertigen Spalten sortieren:
Dies sortiert nach Spalte 0, dann 1, dann 2.
quelle
Aus dem Python-Dokumentations-Wiki können Sie Folgendes tun:
Die Ausgabe ist:
quelle
Für den Fall, dass jemand die Sortierung in einem kritischen Teil seines Programms nutzen möchte, finden Sie hier einen Leistungsvergleich für die verschiedenen Vorschläge:
Es sieht also so aus, als wäre die Indizierung mit argsort die bisher schnellste Methode ...
quelle
In der NumPy-Mailingliste finden Sie eine weitere Lösung:
quelle
a[np.lexsort(a.T[cols])]
. wocols=[1]
in der ursprünglichen Frage.Ich hatte ein ähnliches Problem.
Mein Problem:
Ich möchte eine SVD berechnen und muss meine Eigenwerte in absteigender Reihenfolge sortieren . Aber ich möchte die Abbildung zwischen Eigenwerten und Eigenvektoren beibehalten. Meine Eigenwerte befanden sich in der ersten Zeile und der entsprechende Eigenvektor darunter in derselben Spalte.
Daher möchte ich ein zweidimensionales Array spaltenweise nach der ersten Zeile in absteigender Reihenfolge sortieren.
Meine Lösung
Wie funktioniert das?
a[0,]
ist nur die erste Zeile, nach der ich sortieren möchte.Jetzt benutze ich argsort, um die Reihenfolge der Indizes zu erhalten.
Ich benutze,
[::-1]
weil ich absteigende Reihenfolge brauche.Zuletzt verwende ich
a[::, ...]
, um eine Ansicht mit den Spalten in der richtigen Reihenfolge zu erhalten.quelle
Ein etwas komplizierteres
lexsort
Beispiel - absteigend in der 1. Spalte, sekundär aufsteigend in der 2 .. Die Tricks dabeilexsort
sind, dass es nach Zeilen sortiert (daher die.T
) und der letzten Priorität einräumt.quelle
Hier ist eine andere Lösung, die alle Spalten berücksichtigt (kompaktere Art der Antwort von JJ );
Sortieren mit lexsort,
Ausgabe:
quelle
Verwenden Sie einfach sort, und verwenden Sie die Spaltennummer, nach der Sie sortieren möchten.
quelle
Es ist eine alte Frage, aber wenn Sie dies auf Arrays mit mehr als 2 Dimensionen verallgemeinern müssen, ist hier die Lösung, die leicht verallgemeinert werden kann:
Dies ist ein Overkill für zwei Dimensionen und
a[a[:,1].argsort()]
würde pro @ steves Antwort ausreichen, diese Antwort kann jedoch nicht auf höhere Dimensionen verallgemeinert werden. In dieser Frage finden Sie ein Beispiel für ein 3D-Array.Ausgabe:
quelle