Ich habe eine ziemlich große Punkt-Feature-Class in einer Datei-Geodatabase (~ 4 000 000 Datensätze). Dies ist ein reguläres Punktraster mit einer Auflösung von 100 m.
Ich muss eine Art Verallgemeinerung auf dieser Ebene durchführen. Dazu erstelle ich ein neues Gitter, in dem jeder Punkt in der Mitte von 4 "alten" Punkten liegt:
* * * *
o o o
* * * *
o o o
* * * *
[*] = Punkt des ursprünglichen Gitters - [o] = Punkt des neuen Gitters
Der Attributwert jedes neuen Punktes wird basierend auf den gewichteten Werten seiner 4 Nachbarn im alten Raster berechnet. Ich schleife also alle Punkte meines neuen Gitters und für jeden von ihnen alle Punkte meines alten Gitters, um die Nachbarn zu finden (indem ich die Werte von X und Y in der Attributtabelle vergleiche). Sobald 4 Nachbarn gefunden wurden, verlassen wir die Schleife.
Hier gibt es keine methodische Komplexität, aber mein Problem ist, dass dieses Skript nach meinen ersten Tests wochenlang abgeschlossen sein wird ...
Sehen Sie eine Möglichkeit, es effizienter zu machen? Ein paar Ideen auf meinem Kopf:
- Indizieren Sie die Felder X und Y => Ich habe das getan, aber keine signifikante Leistungsänderung festgestellt
- Führen Sie eine räumliche Abfrage durch, um die Nachbarn zu finden, anstatt eine auf Attributen basierende. Würde das tatsächlich helfen? Welche räumliche Funktion in ArcGIS sollte die Aufgabe übernehmen? Ich bezweifle, dass sich beispielsweise das Puffern jedes neuen Punkts als effizienter erweisen wird
- Transformieren Sie die Feature-Class in ein NumPy-Array. Würde das helfen? Ich habe bisher nicht viel mit NumPy gearbeitet und würde nicht gerne darauf eingehen, es sei denn, jemand sagt mir, dass dies wirklich dazu beitragen könnte, die Verarbeitungszeit zu verkürzen
- Noch etwas?
quelle
Antworten:
Was wäre, wenn Sie die Punkte in ein numpy-Array einspeisen und einen scipy cKDTree verwenden würden, um nach Nachbarn zu suchen? Mit dieser Technik verarbeite ich LiDAR-Punktwolken mit einer großen Anzahl von Punkten (> 20 Millionen) in mehreren MINUTEN. Es ist die Dokumentation hier für kdtree und hier für numpy Konvertierung. Grundsätzlich lesen Sie das x, y in ein Array und iterieren über jeden Punkt im Array, um Indexe von Punkten innerhalb einer bestimmten Entfernung (Nachbarschaft) von jedem Punkt zu finden. Mit diesen Indizes können Sie dann andere Attribute berechnen.
quelle
Ich bin bei Barbarossa ... bogenförmige Cursor sind wahnsinnig lahm, deshalb benutze ich sie nur, um eine Tabelle oder Feature-Class genau einmal zu durchlaufen. Wenn ich die Arbeit nicht in einem Zyklus erledigen kann, benutze ich den Cursor, um eine andere Art von Datenstruktur aufzufüllen und damit zu arbeiten.
Wenn Sie sich nicht mit Numpy herumschlagen möchten, erstellen Sie einfach ein einfaches Python- Wörterbuch, in dem Sie Ihre Koordinaten als einfachen Textschlüssel verwenden, und geben Sie die für die Berechnung erforderlichen Attribute als Wert des Wörterbuchelements in eine Liste ein .
In einem zweiten Schritt können Sie leicht die Werte abrufen, die Sie zur Berechnung eines Punktes benötigen, indem Sie sie einfach aus Ihrem Wörterbuch abrufen (was aufgrund des Wörterbuch-Hashindex der Elemente unglaublich schnell ist).
quelle
Für ein reguläres Raster sollte es weitaus effizienter sein, in einem Rasterformat zu arbeiten. Konvertieren Sie Ihr erstes Raster in ein Raster. Sie können mit einem bilinearen Interpolator mit derselben Auflösung neu abtasten, aber Ihr Ausgabebild in X und Y um 1/2 Pixel verschieben und wieder zu Punkten zurückkehren, wenn Sie noch Punkte benötigen.
BEARBEITEN: Für komplexe Entscheidungsregeln können Sie jedes der Felder, die Sie als neues Rasterband benötigen, konvertieren. Anschließend erstellen Sie vier Kopien dieser Bänder und verschieben Ihr Raster in die 4 Richtungen um 1/2 Pixel (+50, - 50), (+ 50, + 50), (-50, -50) und (-50, + 50). Dann können Sie die reguläre Kartenalgebra verwenden
quelle
Vielen Dank an alle für Ihre Hilfe!
Ich habe endlich einen sehr nicht-pythonischen Weg gefunden, um dieses Problem zu lösen ... Was tatsächlich die meiste Rechenzeit in Anspruch nahm, war, die 4 Nachbarn jedes Punktes zu finden. Anstatt die X- und Y-Attribute zu verwenden (entweder mit einem Arcpy-Cursor oder in einer anderen Datenstruktur, z. B. einem Python-Ditionär), habe ich schließlich das ArcGIS-Tool Generate Near Table verwendet . Ich gehe davon aus, dass dies die räumlichen Indizes ausnutzt und die Leistungen offensichtlich viel höher sind, ohne dass ich den Index selbst implementieren muss.
quelle
Das Problem mit Cursorn ist, dass Sie sie nur auf eine Weise durchlaufen können und nicht zurückkehren können. Obwohl dies nicht empfohlen wird, können Sie die Feautres in eine Struktur einfügen, wenn Sie sie erneut besuchen möchten.
Wenn Sie Ihre Funktionen in einer einzigen Schleife verarbeiten konnten, empfehle ich, das Recycling zu aktivieren. Dies ist ein Parameter in Ihrer Funktion der Such-Feature-Class, mit dem Python den von alten Features zugewiesenen Speicher wiederverwenden und das Durchlaufen der Features in einem Cursor erheblich beschleunigen kann. Sie können Ihr Raster 80% schneller verarbeiten.
Das Problem ist, dass Sie das Recycling nicht aktivieren können, wenn Sie die von einem Cursor abgerufenen Features speichern möchten.
quelle