Schneiden Sie mehrere 2D-np-Arrays zum Ermitteln von Zonen

8

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:

  • 1-8 für Aspekt (1 = Nordseite, 2 = Nordostseite, usw.)
  • 9-12 für Steigung (9 = sanfte Steigung ... 12 = steilste Steigung)
  • 13-16 für die Höhe (13 = niedrigste Höhen ... 16 = höchste Höhen)

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?

    
user2256085 30.12.2017, 15:24
quelle

5 Antworten

2

Dies kann mit numpy.unique() und dann mit einem Mapping erfolgen :

Code:

%Vor%

Testcode:

%Vor%

Ergebnisse:

%Vor%     
Stephen Rauch 30.12.2017, 16:08
quelle
3

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 :

zu berücksichtigen %Vor%

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 :

%Vor%

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:

%Vor%

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:

%Vor%

durch Berechnung von np.arange als Produkt von Indizes und Schritten:

%Vor%

Also alles zusammensetzen:

%Vor%     
unutbu 30.12.2017 16:16
quelle
1

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%     
asheets 30.12.2017 15:58
quelle
1

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.

%Vor%

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.

    
PM 2Ring 30.12.2017 16:18
quelle
1

Hier ist eine Möglichkeit, dieses Problem mithilfe einer wörterbuchbasierten Suche zu lösen.

%Vor%     
kmario23 30.12.2017 17:17
quelle