Möglichkeiten zur Beschleunigung von Python-Skripten, die als ArcGIS-Tools ausgeführt werden

30

Dies ist eine ziemlich allgemeine Frage. Ich frage mich nur, welche Tipps und Tricks GIS-Programmierer verwendet haben, um arcpy-Skripte zu beschleunigen, die Sie in die Toolbox importieren und ausführen.

Ich arbeite täglich am Schreiben kleiner Skripte, um Nicht-GIS-Benutzern bei der Verarbeitung von GIS-Daten in meinem Büro zu helfen. Ich habe festgestellt, dass die ArcGIS 10.0-Verarbeitung im Allgemeinen langsamer als 9.3.1 ist und manchmal sogar langsamer wird, wenn ein Python-Skript ausgeführt wird.

Ich werde ein bestimmtes Beispiel eines Skripts auflisten, dessen Ausführung mehr als 24 Stunden dauert. Es ist eine Schleife, die den Bereich eines Rasters in einem Puffer für jede Form im Puffer tabellarisch darstellt. Der Puffer hat ungefähr 7000 Formen. Ich glaube nicht, dass es so lange dauern sollte. EIN

while x <= layerRecords:

    arcpy.SetProgressorLabel("Tabulating Row: " + str(x) + " of " + str(ELClayerRecords))
    arcpy.SelectLayerByAttribute_management(Buff,"NEW_SELECTION", "Recno = " + str(x))                                  # Selecting the record
    TabulateArea(Buff, "Recno", MatGRID, "VALUE", ScratchWS + "/tab" + str(z) +".dbf", nMatGRIDc)                          # Tabulate the area of the single row

    arcpy.AddMessage ("          - Row: " + str(x) + " completed")
    x = x + 1
    z = z + 1

Bevor es jemand sagt, habe ich einen tabellarischen Bereich für den gesamten Puffer ausgeführt, aber er erzeugt Fehler, wenn er mit mehr als einem Datensatz ausgeführt wird. Es ist ein fehlerhaftes Werkzeug, aber ich muss es benutzen.

Wie auch immer, wenn jemand Ideen zur Optimierung oder Beschleunigung dieses Skripts hat, wäre er sehr dankbar. Andernfalls haben Sie irgendwelche Tricks zur Beschleunigung von Python, wenn Sie in ArcGIS verwendet werden?

Cody Brown
quelle

Antworten:

25

Einige mögliche Vorschläge zur Beschleunigung Ihres Prozesses sind:

  1. Layer nach Attribut auswählen kann sich in einem Nur-Python-Skript befinden, ohne dass ArcGIS Desktop gestartet werden muss. Sie müssen Ihre "Buff" -Referenz von einer dateibasierten Referenz in eine "ArcGIS-Layer" -Referenz konvertieren, mit der ArcGIS Auswahlabfragen verarbeiten kann. Verwenden Sie arcpy.MakeFeatureLayer_management ("buff", "buff_lyr") über Ihrer "while" -Schleife und ändern Sie dann Ihre Referenzen unter der while-Schleife, um "buff_lyr" zu verwenden.

  2. Verarbeiten Sie so viele Ihrer GP-Vorgänge wie möglich im Arbeitsbereich in_memory. Verschieben Sie Ihre Quelle mit arcpy.CopyFeatures_management (Shapefile, "in_memory \ memFeatureClass") in den Speicher. Dies funktioniert nur dann, wenn Sie über genügend RAM verfügen, um alle benötigten Feature-Classes in den Arbeitsspeicher zu lesen. Beachten Sie jedoch, dass es einige GP-Vorgänge gibt, die nicht über den Arbeitsbereich in_memory ausgeführt werden können (z. B. das Projekt-Tool).

Aus dem ArcGIS 9.3-Online-Hilfeartikel " Zwischendaten und der Arbeitsbereich " (Hinweis: Diese Sprache wurde aus der 10.0- und 10.1-Hilfe entfernt):

ANMERKUNG: In den Arbeitsbereich in_memory können nur Tabellen und Feature-Classes (Punkte, Linien, Polygone) geschrieben werden. Der Arbeitsbereich in_memory unterstützt keine erweiterten Geodatabase-Elemente wie Subtypen, Domänen, Darstellungen, Topologien, geometrische Netzwerke und Netzwerk-Datasets. Es können nur einfache Features und Tabellen geschrieben werden.

In ArcGIS 10.1-Online-Hilfeartikel " Verwenden des Arbeitsbereichs im Arbeitsspeicher ":

Bei der Entscheidung, die Ausgabe in den Arbeitsbereich im Arbeitsspeicher zu schreiben, müssen die folgenden Überlegungen getroffen werden:

  • Daten, die in den Arbeitsbereich im Arbeitsspeicher geschrieben werden, sind temporär und werden gelöscht, wenn die Anwendung geschlossen wird.
  • Tabellen, Feature-Classes und Raster können in den Arbeitsbereich im Arbeitsspeicher geschrieben werden.
  • Der speicherinterne Arbeitsbereich unterstützt keine erweiterten Geodatabase-Elemente wie Subtypen, Domänen, Darstellungen, Topologien, geometrische Netzwerke und Netzwerk-Datasets.
  • Feature-Datasets oder -Ordner können im Arbeitsbereich im Arbeitsspeicher nicht erstellt werden.
RyanDalton
quelle
1
Das ist fantastisch! Ich habe nach einer Möglichkeit gesucht, Auswahlen außerhalb von ArcMap zu verwenden, war jedoch bisher erfolglos. In Bezug auf dieses Problem hat es meine Zeit pro Zeile von 20 Sekunden auf ungefähr 13 Sekunden gesenkt. Aber ich habe eine schnelle andere Arbeit gemacht und den MakeFeatureLayer innerhalb der Schleife gemacht und es ging auf 9 Sekunden runter. Dazu habe ich aus jeder Form ein Feature erstellt und nicht aus der Feature-Ebene eine Tabelle erstellt. Ich würde es gerne noch weiter reduzieren, aber es ist schon ein viel schnellerer Prozess!
Cody Brown
Verwenden Sie, wie in Nummer 2 erwähnt, die CopyFeatures, um eine Kopie Ihrer Quelldaten in_memory zu erstellen, und erstellen Sie dann Ihre Feature_Layer für die in_memory-Quelle. Während die anfängliche Kopie in den Speicher einige Sekunden im Voraus dauern kann, können Sie feststellen, dass die Verarbeitung von Kopierfunktionen + tabulierten_Bereichen eine schnellere Gesamtverarbeitungszeit hat als Ihr aktuelles Modell.
RyanDalton
Ich habe das auch versucht und es scheint, als würde diese Lösung den Loop-Prozess beschleunigen, aber das ist nicht der Fall. Das Erstellen des Feature-Layers in der Schleife dauert ca. 8-10 Sekunden pro Schleife, während das Erstellen des Feature-Layers vor der Schleife 11-14 Sekunden pro Schleife dauert. Ich bin mir nicht sicher, warum, da Ihre Lösung so klingt, als würde sie schneller verarbeitet. Ich habe 8 GB RAM, daher bezweifle ich, dass dies das Problem ist.
Cody Brown
Das Kopieren der Features nach in_memory vor der Schleife und das anschließende Erstellen des Feature-Layers in der Schleife führt zu einer etwas schnelleren Leistung. Es bleiben so ziemlich 8 Sekunden pro Zeile für jede Schleife. Damit sinkt die Gesamtprozesszeit von 26 Stunden auf 22.
Cody Brown
Nachdem ich Ihre Ideen hinzugefügt habe, hat sich mein Skript dramatisch verbessert. Vielen Dank für Ihre und jedermanns Hilfe!
Cody Brown
28

Allgemeine Python-Optimierungstechniken können Ihnen viel Zeit sparen.

Eine wirklich gute Technik, um zu ermitteln, wo sich die Überhänge in Ihrem Skript befinden, ist die Verwendung des integrierten cProfile-Moduls:

from cProfile import run
run("code") # replace code with your code or function

Wenn Sie anhand eines kleinen Datenmusters testen, können Sie genau bestimmen, welche Funktionsaufrufe am meisten Zeit in Anspruch nehmen.

Allgemeine Hinweise für schnelleren Python-Code:

  • Listenverständnisse sind im Allgemeinen schneller als Schleifen
  • Generatoren produzieren jeweils einen Artikel, anstatt die gesamte Liste auf einmal zu produzieren
  • Verwenden Sie xrange anstelle von range in Python 2 (in 3 nicht erforderlich)
  • Sets können Preform-Listen ausgeben, um festzustellen, ob ein Element im Set vorhanden ist, sind jedoch im Allgemeinen langsamer als Listen, wenn es darum geht, den Inhalt der Quelle zu durchlaufen
  • Funktionsaufrufe können , um die Leistung teuer Quelle
  • Weitere Tipps und Details finden Sie hier, Tipps zur Python-Leistung und hier, 10 Tipps und Probleme zur Python-Optimierung

In Bezug auf Ihr Skript kann ich die ArcPy-Aspekte nicht kommentieren, da ich Arc nicht auf diesem Computer installiert habe. Vielleicht möchten Sie jedoch versuchen, eine for-Schleife anstelle einer while-Schleife zu verwenden, um festzustellen, ob sich hierdurch etwas verbessert. Auch x = x + 1 kann als x + = 1 geschrieben werden:

for record in layerRecords:
arcpy.SetProgressorLabel("Tabulating Row: " + str(x) + " of " + str(ELClayerRecords))
arcpy.SelectLayerByAttribute_management(Buff,"NEW_SELECTION", "Recno = " + str(x))                                  # Selecting the record
TabulateArea(Buff, "Recno", MatGRID, "VALUE", ScratchWS + "/tab" + str(z) +".dbf", nMatGRIDc)                          # Tabulate the area of the single row

arcpy.AddMessage ("          - Row: " + str(x) + " completed")
x+=1
y+=1
James Milner
quelle
1
Ich habe die beiden Links, die Sie in Ihrem letzten Aufzählungszeichen hinterlassen haben, verwendet und konnte meinem Skript mit ein paar schnellen Korrekturen wirklich helfen!
Cody Brown
Wenn ich zwei richtige Antworten vergeben könnte, würde ich. Während Ihre Antwort wirklich viele Ideen zur Beschleunigung von Python enthielt, bot @RyanDalton die Ideen an, die den größten Einfluss hatten. Danke vielmals!
Cody Brown
13

Stellen Sie sicher, dass Sie auf das interne Laufwerk des Computers schreiben. Das Erreichen des Netzwerks, wenn dies nicht erforderlich ist, kann die Verarbeitung erheblich verlangsamen. Es kann sogar schneller sein, die Daten als ersten Schritt im Prozess zu kopieren, um die nachfolgenden Lese- und Schreibvorgänge so schnell wie möglich durchzuführen

Das vollständige Ausführen des Skripts außerhalb von ArcMap kann viel schneller sein. Wenn während der Verarbeitung keine Karte erforderlich ist, verwenden Sie ArcMap nicht.

mhoran_psprep
quelle
Ich habe festgestellt, dass das Ausführen eines Skripts in einem Modell aus ArcCatalog (in einem Calculate ValueDialogfeld) schneller ausgeführt wird als das Ausführen desselben Skripts aus dem ArcPy-Fenster in ArcMap. Das ist jedoch nur eine anekdotische Beobachtung.
Cindy Jayakumar
1
Ich glaube, ich brauche eine Karte, damit Tabulate richtig funktioniert, aber ich werde es versuchen. Wenn es außerhalb von ArcMap funktioniert, würde es sich wahrscheinlich beschleunigen. Auch laufe ich schon von der lokalen Platte, die schon die Geschwindigkeit des Skripts verdoppelt hat.
Cody Brown
Leider funktioniert die Auswahl nicht außerhalb von ArcMap, und dies ist erforderlich, da ich die Tabellierung Form für Form vornehmen muss.
Cody Brown
3
@ CodyBrown- Sie sind falsch in Bezug auf "Auswählen", wenn Sie nicht außerhalb einer ArcMap-Sitzung arbeiten. Siehe meine Antwort zur Verwendung des MakeFeatureLayer-Tools.
RyanDalton
Ryan hat recht. Wenn das Auswahlwerkzeug alleine verwendet wird, wird eine Tabellenansicht Ihrer räumlichen Daten oder Tabellendaten erstellt. Wenn Sie es in ModelBuilde oder in einem Skript verwenden, müssen Sie eine Ansicht erstellen und in Ihrem Fall mit dem MakeFeatureLayer-Tool erstellen.
dchaboya
6

Dies ist möglicherweise keine Antwort auf Ihre Frage zum Ausführen von ArcPy-Tools in ArcMap. Wenn ich jedoch eine komplexe Verarbeitung mit Geoverarbeitungs-Tools und Python ausführen muss, kann ich sie außerhalb des GIS-Systems mit dem IDE PyScripter ausführen . Ich habe festgestellt, dass es schneller läuft. Ich habe auch eine RAMDISK für kleine temporäre Ausgabedatensätze verwendet (ein bisschen wie die in_memory- Arbeitsbereich)

Nun, das sind meine Top-Tipps! :)

Hornbydd
quelle
2
Um diese Antwort etwas zu trüben, fügen viele beim Ausführen von Skripten aus Python-IDEs eine Traceback-Funktion ein, um das Überwachen von Variablen und andere verschiedene Debugging-Hilfen zu unterstützen. Diese Funktion kann Skripte massiv verlangsamen, wenn sie zu viel bewirkt, da sie STÄNDIG aufgerufen wird, und manchmal wird dies implizit ohne Benutzereingriff installiert. Es gab einen bestimmten pathologischen Fall, bei dem ein in ArcMap ausgeführtes Python-Skript in 4 Minuten ausgeführt wurde, während dasselbe Skript von Wing IDE 3 Stunden dauerte. Sobald es von Python.exe ohne Wing ausgeführt wurde, kehrte es in das Laufzeitgebiet von ca. 2-3 Minuten zurück.
Jason Scheirer
1
Ich hatte Kopfschmerzen beim Optimieren meiner Skripte auf ArMap, manchmal kann ich es nicht vollständig, bis ich mich an Pyscripter gewandt habe. Es kann die Ausführungszeit im Vergleich zu Arcmap verkürzen, ohne einen Optimierungstipp zu verwenden.
Geogeek
@JasonScheirer hast du den Tweak in Wing gefunden, um das auszuschalten? Ich bin mir sicher, dass es einen gibt.
Curtis Price
5

Versuchen Sie, arcpy.SetProgressorLabel zu kommentieren, und sehen Sie, wie viel Sie beschleunigen. Ich habe festgestellt, dass jede Bildschirmausgabe, die auf DOS-Daze zurückgeht, die Verarbeitungszeiten drastisch verlangsamt. Wenn Sie diese Ausgabe wirklich sehen müssen, versuchen Sie, sie bei jeder N-ten Schleife anzuzeigen.

user30749
quelle
4

Stellen Sie sicher, dass Sie alle import xxxxnicht verwendeten Zeilen entfernen .

(dh wenn Sie noch keine mathematischen Funktionen verwenden import Math, dauert es einige Zeit, bis das Skript geladen ist.)

Dies hat zwar keine großen Auswirkungen auf einzelne Skripte, die ausgeführt werden (wie z. B. Ihre), wirkt sich jedoch auf alle Skripte aus, die häufig und wiederholt ausgeführt werden.

Nagytech
quelle
7
Ich bezweifle, dass ein Standard-Python-Modul mehr als ein Tausendstel der Zeit benötigt, die das arcpy-Modul für die Initialisierung benötigt.
blah238
1
@ blah238 import Mathwar wohl ein schlechtes Beispiel. Das Laden einiger größerer ArcPy-Bibliotheken nimmt jedoch viel Zeit in Anspruch.
Nagytech
1
Dies ist immer noch nur Sekunden (höchstens!), nicht Stunden
Mike T
1
@MikeToews Bei Skripten, die häufig und wiederholt ausgeführt werden, summieren sich einige Sekunden über einige Tage / Wochen usw. Obwohl dies das Hauptproblem des OP nicht lösen konnte, bat er um allgemeine Tipps.
Nagytech