Ich möchte eine dichte quadratische Übergangsmatrix direkt ändern, indem ich die Reihenfolge mehrerer Zeilen und Spalten mithilfe der Numpy-Bibliothek von Python ändere. Mathematisch entspricht dies einer Vormultiplikation der Matrix mit der Permutationsmatrix P und einer Nachmultiplikation mit P ^ -1 = P ^ T, dies ist jedoch keine rechnerisch sinnvolle Lösung.
Im Moment tausche ich manuell Zeilen und Spalten aus, aber ich hätte erwartet, dass numpy eine nette Funktion f (M, v) hat, wobei M n Zeilen und Spalten und v n Einträge hat, so dass f (M, v) aktualisiert wird M entsprechend der Indexpermutation v. Möglicherweise scheitere ich gerade am Suchen des Internets.
So etwas könnte mit Numpys "Advanced Indexing" möglich sein, aber ich verstehe, dass eine solche Lösung nicht vorhanden wäre. Auch für einige einfache Situationen kann es ausreichend sein, eine Indexpermutation nur separat zu verfolgen, aber dies ist in meinem Fall nicht zweckmäßig.
Hinzugefügt:
Wenn von Permutationen die Rede ist, bedeutet dies manchmal nur das Abtasten von zufälligen Permutationen, beispielsweise als Teil einer Prozedur zum Erhalten von p-Werten in Statistiken. Oder sie bedeuten das Zählen oder Aufzählen aller möglichen Permutationen. Ich spreche nicht über diese Dinge.
Hinzugefügt:
Die Matrix ist klein genug, um in den Arbeitsspeicher des Desktops zu passen, aber groß genug, um sie nicht unnötig zu kopieren. Eigentlich würde ich gerne Matrizen verwenden, die so groß wie möglich sind, aber ich möchte nicht mit der Unannehmlichkeit fertig werden, sie nicht im RAM zu halten, und ich führe O (N ^ 3) LAPACK-Operationen auf der Matrix aus, was auch der Fall wäre Begrenzen Sie die praktische Matrixgröße. Ich kopiere derzeit Matrizen dieser Größe unnötig, aber ich hoffe, dass dies für die Permutation leicht vermieden werden kann.
quelle
M[v]
, die Zeilen zu permutieren.Antworten:
Laut der Dokumentation gibt es in numpy keine direkte Permutationsmethode wie ndarray.sort .
Ihre Optionen lauten also (vorausgesetzt, esN×N
M
handelt sich um eine Matrix und den Permutationsvektor).p
SpeicheraufwandN
SpeicheraufwandN2
Hoffe, dass diese suboptimalen Hacks nützlich sind.
quelle
Warnung: Das folgende Beispiel funktioniert ordnungsgemäß, aber die Verwendung des vollständigen Parametersatzes, der am Ende des Dokuments vorgeschlagen wird, macht einen Fehler oder zumindest eine "undokumentierte Funktion" in der Funktion numpy.take () sichtbar. Einzelheiten finden Sie in den Kommentaren unten. Fehlerbericht eingereicht .
Sie können dies direkt mit der take () - Funktion von numpy tun , aber es erfordert ein wenig Reifenspringen.
Hier ist ein Beispiel für eine zufällige Permutation der Zeilen einer Identitätsmatrix:
Um dies zu tun, müssen Sie lediglich den "out" -Parameter so festlegen, dass er mit dem Eingabearray identisch ist, UND Sie müssen mode = "clip" oder mode = "wrap" einstellen. Wenn Sie den Modus nicht festlegen, wird eine Kopie erstellt, um den Array-Status in einer Python-Ausnahme wiederherzustellen (siehe hier) .
Abschließend scheint take eine Array-Methode zu sein, also nicht
du könntest anrufen
wenn das mehr nach deinem geschmack ist. Insgesamt sollten Sie also ungefähr so aussehen:
Um sowohl Zeilen als auch Spalten zu permutieren, muss man entweder zwei Mal damit arbeiten oder ein paar hässliche Spielereien mit numpy.unravel_index ziehen , die mir Kopfschmerzen bereiten .
quelle
1.6.2
,test take, not overwriting: True
,test not-in-place take: True
,test in-place take: False
,rr [3, 7, 8, 1, 4, 5, 9, 0, 2, 6]
,arr [30 70 80 70 40 50 90 30 80 90]
,ref [30 70 80 10 40 50 90 0 20 60]
. Sonp.take
zumindest für numpy 1.6.2 ist nicht bekannt , auf eine in-Place - Permutation und Verwirrungen , Dinge zu tun.Wenn Sie eine dünne Matrix im
COO
Format gespeichert haben , kann Folgendes hilfreich seinA
COO
perm
numpy.array
quelle
C00
Matrix mit geringer Dichte an erster Stelle?int
float
float
numpy.ndarray
s halten könnte.Ich habe nicht genug Reputation, um einen Kommentar abzugeben, aber ich denke, die folgende SO-Frage könnte hilfreich sein: https://stackoverflow.com/questions/4370745/view-onto-a-numpy-array
Die grundlegenden Punkte sind, dass Sie Basic Slicing verwenden können und eine Ansicht auf das Array erstellen, ohne es zu kopieren. Wenn Sie jedoch Advanced Slicing / Indexing ausführen, wird eine Kopie erstellt.
quelle
Wie wäre es mit
my_array [:, [0, 1]] = my_array [:, [1, 0]]
quelle