Mit diesem kleinen reproduzierbaren Beispiel konnte ich bisher kein neues Integer-Array aus 3 Arrays generieren, das eindeutige Gruppierungen über alle drei Input-Arrays enthält.
Die Arrays sind mit topographischen Eigenschaften verknüpft:
%Vor%Die Idee ist, dass die geografischen Konturen in drei verschiedene Eigenschaften unter Verwendung von GIS-Routinen aufgeteilt werden:
Die kleine Grafik unten versucht, die Art von Ergebnis darzustellen, nach dem ich gesucht habe (das Feld wird unten links gezeigt). Beachten Sie, dass die "Antwort" in der Grafik nur eine mögliche Antwort ist. Ich bin nicht besorgt über die endgültige Anordnung von Ganzzahlen im resultierenden Array, solange das letzte Array eine Ganzzahl in jedem Zeilen- / Spaltenindex enthält, die eindeutige Gruppierungen identifiziert.
Beispielsweise haben die Array-Indizes bei [0,1] und [0,2] den gleichen Aspekt, die gleiche Steigung und die gleiche Elevation und erhalten daher im resultierenden Array den gleichen Ganzzahl-Bezeichner.
Hat numpy eine eingebaute Routine für so etwas?
Dies kann mit numpy.unique()
und dann mit einem Mapping erfolgen :
Jede Position im Gitter ist einem Tupel zugeordnet, das aus einem Wert von besteht
asp
, slp
und elv
. Zum Beispiel hat die obere linke Ecke das Tupel (8,9,13)
.
Wir möchten dieses Tupel einer Zahl zuordnen, die dieses Tupel eindeutig identifiziert.
Eine Möglichkeit wäre, an (8,9,13)
als Index in das 3D-Array zu denken
%Code%. Dieses bestimmte Array wurde ausgewählt
um die größten Werte in np.arange(9*13*17).reshape(9,13,17)
, asp
und slp
:
Nun können wir das Tupel (8,9,13) der Nummer 1934 zuordnen:
%Vor%Wenn wir dies für jeden Standort im Raster tun, erhalten wir für jeden Standort eine eindeutige Nummer. Wir könnten genau hier enden und diese eindeutigen Zahlen als Etiketten verwenden.
Oder wir können kleinere Integer-Label erzeugen (beginnend bei 0 und steigend um 1)
mit elv
mit
np.unique
:
Also zum Beispiel
%Vor%ergibt
%Vor% Die obige Methode funktioniert gut, solange die Werte in return_inverse=True
, asp
und slp
kleine ganze Zahlen sind. Wenn die Ganzzahlen zu groß wären, könnte das Produkt ihrer Höchstwerte den maximal zulässigen Wert überschreiten, den man an elv
übergeben kann. Darüber hinaus wäre die Erzeugung einer derart großen Anordnung ineffizient.
Wenn die Werte Floats wären, könnten sie nicht als Indizes in das 3D-Array np.arange
interpretiert werden.
Um diese Probleme zu beheben, verwenden Sie x
, um die Werte in np.unique
, asp
und slp
zuerst in eindeutige Ganzzahlen umzuwandeln:
was das gleiche Ergebnis wie oben zeigt, funktioniert aber auch wenn elv
, asp
, slp
Floats und / oder große ganze Zahlen sind.
Schließlich können wir die Erzeugung von elv
vermeiden:
durch Berechnung von np.arange
als Produkt von Indizes und Schritten:
Also alles zusammensetzen:
%Vor%Dies scheint ein ähnliches Problem zu sein, wenn eindeutige Regionen in einem Bild markiert werden sollen. Dies ist eine Funktion, die ich geschrieben habe, um dies zu tun, obwohl Sie zuerst Ihre 3 Arrays zu 1 3D-Array verketten müssen.
%Vor%Dadurch werden eindeutige 3-Wert-Kombinationen beschriftet, während Zonen Zonen zugeordnet werden, die die gleiche 3-Wert-Kombination haben, aber nicht miteinander in Kontakt stehen.
%Vor%gibt zurück:
%Vor% Hier ist eine einfache Python-Methode mit itertools.groupby
. Es erfordert die Eingabe von 1D-Listen, aber das sollte kein großes Problem sein. Die Strategie besteht darin, die Listen zusammen mit einer Indexnummer zusammenzufassen und dann die resultierenden Spalten zu sortieren. Wir gruppieren dann identische Spalten und ignorieren die Indexnummer beim Vergleich von Spalten. Dann sammeln wir die Indexnummern aus jeder Gruppe und verwenden sie, um die endgültige Ausgabeliste zu erstellen.
Ausgabe
%Vor%Es gibt keine Notwendigkeit, diese zweite Sortierung durchzuführen, wir könnten einfach eine einfache Listenkomposition verwenden
%Vor%oder Generatorausdruck
%Vor%Ich habe es nur so gemacht, dass meine Ausgabe mit der Ausgabe in der Frage übereinstimmt.
Tags und Links python numpy multidimensional-array numpy-ndarray