Erhöhen der Geschwindigkeit von Python-Skripten mit arcpy

8

Update 4/11/2014

Es sieht so aus, als ob das Skript im Tool "Funktionen löschen" hängen geblieben ist, also habe ich zu "Tabelle abschneiden" gewechselt, wie in der folgenden Antwort vorgeschlagen. Ich habe auch die nicht verwendeten Variablen aus dem Append-Tool entfernt.

Update 10.04.2014

Ich habe dieses Skript auf dem Computer meines Kollegen ausgeführt (sein Computer hat mehr Speicher UND enthält ArcGIS 10.0 / Python26) und es wurde schnell ausgeführt. Hurra! Sobald mein technischer Support die ArcGIS 10.0-CD gefunden hat, werde ich sie installieren und testen, um festzustellen, ob dies die Geschwindigkeit auf meinem Computer verbessert. Um es klar auszudrücken, führen wir dasselbe Skript aus, unser Netzlaufwerk und unsere Datenbankverbindung sind identisch zugeordnet und die Druckanweisungen sind identisch. Ich werde hier ein Update veröffentlichen, sobald dies passiert.

Aktualisierungen beenden

Ich muss die Geschwindigkeit einiger Python-Skripte erhöhen, die Updates für eine Oracle-Datenbank ausführen. Ich hatte diese Python-Skripte über ein Jahr lang gut laufen lassen, über geplante Aufgaben und Batch-Dateien, um die Skripte zu initiieren. Letzte Woche bin ich von einem XP auf einen Windows 7-Computer und ArcGIS 10.0 -> 10.1 gewechselt. Seitdem sind die Skripte furchtbar langsam geworden. Wenn ich dieses Skript mit einer kleinen Feature-Class (mit ~ 20 Features) ausführe, wird es in 30 Sekunden ausgeführt. Wenn ich eine mittlere Feature-Class (~ 80.000 Datensätze) verwende, läuft sie in 15 Minuten. Die Feature-Class, die ich wirklich schnell übertragen muss, enthält ungefähr 1.000.000 Datensätze. Das Skript reicht nur bis zur print-Anweisung, um zu überprüfen, ob die Dateien vorhanden sind (if-Anweisung im Code unten). Dieser Vorgang würde auf meinem XP / ArcGIS 10.0-Computer nur 35 Minuten dauern.

Unten ist der vereinfachte Code, mit dem ich getestet habe. Hat jemand Vorschläge, was ich tun kann, um die Geschwindigkeit zu erhöhen? Danke, Patty

import arcpy, os, sys
from arcpy import env
arcpy.env.overwriteOutput = True
from datetime import datetime
import smtplib
import string
import urllib

#Define variables
inWorkspace = "O:/LANDING_PAD/BOE/example.gdb" 
lpFeatures = inWorkspace + os.sep + "fc1"
outWorkspace =  "Database Connections\\THIS.sde"
arcpy.env.workspace = outWorkspace
workspace = ""
copyFC = outWorkspace + os.sep + "SDE.fc1_1" #The feature class the script will update via delete and append
schema_type = "NO_TEST"
fieldMappings = ""
subtype = ""
t = datetime.now()
print "This script began at: " + str(t)

if arcpy.Exists(lpFeatures) is True and arcpy.Exists(copyFC) is True:
    print "Both files exist. Beginning delete..."
    arcpy.DeleteFeatures_management(copyFC) #(copyFC)

    print "ALL DONE DELETING!"

    arcpy.Append_management(lpFeatures, copyFC, schema_type, fieldMappings, subtype) #Append data from landing pad to db
    print "ALL DONE APPENDING!"
    record_count = arcpy.GetCount_management(lpFeatures)
    print record_count
    r = datetime.now()
    print "This script ended at: " + str(r)
Patty Jula
quelle
1
Ich habe arcpy nicht verwendet, aber ich habe Python und viele parallele Systeme in C # geschrieben. Ist es möglich, dass Sie Ihre Arbeit in kleinere Teile aufteilen und diese parallel bearbeiten? Versenden Sie entweder mehrere Python-Prozesse oder versuchen Sie, Threading zu verwenden. Es könnte chaotisch werden, besonders wenn arcpy nicht threadsicher ist, aber es könnte sich auszahlen, wenn Sie viel zu tun haben! Es kann hilfreich sein, auch nach dem Stapelüberlauf zu fragen.
Jocull
Die Langsamkeit liegt darin, dass Sie alle einzelnen Features löschen und an die leere Feature-Class anhängen. Gibt es einen Grund, warum Sie nicht die gesamte Feature-Class mit löschen Delete_management()und dann mit CopyFeatures_management()oder neu erstellen können FeatureClassToFeatureClass_conversion()?
nmpeterson
2
Haben Sie eine Profilerstellung durchgeführt ( docs.python.org/2/library/profile.html ), um festzustellen, wo der Großteil Ihrer Verarbeitung stattfindet? Es wäre interessant, Ihre Ergebnisse zu sehen.
Aaron
1
@jocull Ja, ich habe darüber nachgedacht, etwas zusammenzustellen, das Multiprocessing verwendet, aber ich war ein wenig festgefahren, wie schnell die Skripte unter XP / ArcGIS 10.0 und unter Windows 7 / 10.1 so langsam waren. Aaron, ja, es wäre cool zu sehen, wo die Verarbeitung stattfindet. Ich werde das Profil des Skripts untersuchen. Danke, Patty
Patty Jula
Ich habe oben ein Update gepostet. Grundsätzlich laufen die Skripte schnell auf dem Computer meines Kollegen, was gut ist.
Patty Jula

Antworten:

7

Ich wollte zuerst einen Kommentar abgeben, aber dann schien es angemessener, ihn als Antwort zu verpacken (auch wenn er möglicherweise unvollständig ist).

Ich habe Ihren Code auf meinem Computer (Top-Hardware-Laptop mit SSD) ausgeführt und eine Datei-Geodatabase-Feature-Class an eine SQL Server-Geodatabase-Feature-Class auf demselben Computer angehängt, was ungefähr 13 Minuten gedauert hat. Ich kann Ihnen nicht sicher sagen, warum sich die Ausführungsgeschwindigkeit in Ihrer Umgebung so stark unterscheidet (10.0 >> 10.1), aber Sie haben um Vorschläge gebeten , wie Sie die Geschwindigkeit erhöhen können . Hier sind einige Ideen, die die Geschwindigkeit erhöhen könnten das Skript auszuführen.

1) Ich führe das Skript über die Befehlszeile aus, was dem Ausführen einer .bat-Datei entspricht (ich führe das Skript in der 64-Bit-Variante aus, ich habe ArcGISx6410.2 64-Bit-Python installiert).

c:\Python27\ArcGISx6410.2\python.exe c:\scripts\appendfc.py

Nach meiner Erfahrung ist es im Allgemeinen schneller, eine 64-Bit-Version von Python auszuführen, um lange und schwere GP-Operationen wie Anhängen auszuführen. Sie möchten also sicherstellen, dass Sie diese Version von Python ausführen, wenn Sie das Skript ausführen.

2) Ich würde nicht empfehlen, zu verwenden arcpy.DeleteFeatures_management; Es ist viel langsamer als das Ausführen von " Tabelle abschneiden", da letztere keine Datenbanktransaktionen verwendet, was die Leistung beim zeilenweisen Löschen verbessert.

Sie haben erwähnt, dass das Skript nur bis zur print-Anweisung reicht, um zu überprüfen, ob die Dateien vorhanden sind (if-Anweisung im Code) . Es besteht eine gute Chance, dass weiterhin Zeile für Zeile gelöscht wird. Dies kann ein sehr langsamer Prozess sein, wenn Sie auf eine Tabelle in einer entfernten Oracle-Datenbank (oder einer beliebigen DBMS-Datenbank) zugreifen. Versuchen Sie, das Skript mit "Tabelle abschneiden" auszuführen, jedoch ohne Anhängen, um den Leistungsunterschied in der Löschphase festzustellen.

3) Sie scheinen "Database Connections\\THIS.sde"im Code zu verwenden. Es ist jedoch besser, auf die Verbindungsdatei selbst (.sde-Datei) mit dem Dateisystem oder dem UNC-Pfad zu verweisen, nicht auf den Ordner "Datenbankverbindungen" des Katalogfensters. Sie können auf die .sde-Datei zugreifen, die unter erstellt wurde C:\Users\%user%\AppData\Roaming\ESRI\Desktop10.1\ArcCatalog. Sie können diese .sde-Datei nach Bedarf verschieben und in den Ordner legen, auf den das Python-Skript Zugriff hat.

4) In der arcpy.Append_managementFunktion verwenden Sie einige leere Parameter. Theoretisch sollte es keinen Unterschied machen, aber ich würde vorschlagen, die Funktion auszuführen, ohne diese Parameter anzugeben, nur weil Sie sie nicht benötigen. Sie wissen nie, was sich hinter den Kulissen abspielt und ob diese leeren Zeichenfolgen irgendwann ausgewertet werden und ob dies die Leistung beeinträchtigen kann. Gehen Sie einfach mit arcpy.Append_management(lpFeatures, copyFC, schema_type)und geben Sie keine Parameter an, für die Sie keine Werte angeben.

5) Ich rate davon ab, os.sepbeim Erstellen eines Pfads zu einer Feature-Class zu verwenden. Verwenden Sie os.path.join(geodatabase,featureclassname)stattdessen dafür. Es ist einfach sauberer und lesbarer.

Sie können der Frage weitere Details hinzufügen, nachdem Sie die oben genannten Schritte ausprobiert und einige Tests und Codeüberprüfungen durchgeführt haben.

Ein paar gute Fragen, die Sie lesen sollten, um mehr darüber zu erfahren, wie Sie die Python-Skripte in ArcGIS beschleunigen können:

Leistung von ArcGISScripting und großen räumlichen Datensätzen

Hintergrund-Geoverarbeitung (64-Bit)

Das Arcgis CopyFeatures-Tool ist beim Exportieren in SDE extrem langsam

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

Überlegungen zur Geoverarbeitung für ArcSDE-Daten

Alex Tereshenkov
quelle
Vielen Dank, du hast meinen Freitag gerettet. Ich wollte hinzufügen, dass ich eine Datenbank in einer Batch-Datei mit dem Namen aufrufen kann "Database Connections\\THIS.sde". Vielleicht liegt das daran, dass die Batchdatei nur die Python-Skripte initiiert, die diese Variable verwenden? Ich kann keine Datenbank mit dem Namen haben, THIS database.sdedie mir fremd ist, da dort ein Leerzeichen vorhanden ist Database Connections.
Nochmals
Ich bin froh, dass es hilfreich war. 1. Wie sieht es jetzt leistungsmäßig aus? 2. Interessant mit "Datenbankverbindungen". Ich war mir so sicher, dass Sie im Katalogfenster nicht auf diesen "Ordner" verweisen können, wenn Sie das Skript nicht über die ArcGIS Desktop-Benutzeroberfläche ausführen, aber ich habe mich geirrt. Ich habe meine Antwort aktualisiert, um dies widerzuspiegeln. 3. Sie können die Verbindungsdatei "this database.sde" haben. Leerzeichen können verwendet werden. Sie können jedoch keine Datenbank in Oracle mit Leerzeichen haben, mit der DBMS genau so funktioniert.
Alex Tereshenkov
Die Leistung ist jetzt verbessert. Der Prozess zum Ausführen der Feature-Class für Millionen Datensätze (von Adresspunkten) wird jetzt auf dem Windows 7 / ArcGIS 10.1-Computer ausgeführt (bevor das Tool zum Löschen von Features nur eingefroren wurde). Es dauert 3 Stunden, um diesen gesamten Prozess auszuführen. Dieser Vorgang dauerte auf meinem XP / 10.0-Computer 50 Minuten. Ist dieser Link das, worauf Sie sich mit Punkt 1 in Ihrer Antwort bezogen haben?
Patty Jula
@ PattyJula, richtig, es ist dieser. Sie müssen keine Hintergrundverarbeitungssoftware installieren / verwenden, die oben installiert ist. Sie müssen nur die 64-Bit-Version von Python verwenden, wenn Sie Ihr Skript ausführen.
Alex Tereshenkov
Danke für den Vorschlag. Ich habe 64-Bit-Python und einen 64-Bit-Oracle-Client installiert. Meine Skripte werden immer noch nicht mit der Geschwindigkeit ausgeführt, die sie mit meiner XP / ArcGIS 10.0-Konfiguration ausgeführt haben. Ich werde heute Abend eine Aufgabe zum Ausführen der Batchdateien und Python-Skripte planen. Wenn sich die Geschwindigkeit nicht verbessert, muss ich möglicherweise einen anderen Computer einrichten, auf dem ArcGIS 10.0 ausgeführt wird.
Patty Jula
1

Ich hoffe, dass dieses Beispiel auch bei der Beantwortung der Frage hilft und auf neuerer Software basiert. Es baut auf den oben genannten Antworten und Kommentaren auf.

Installieren:

  1. Windows 7
  2. SQL Server 2012 R2
  3. ArcGIS 10.2.2 (Server und Desktop)

Die Ladung musste jede Nacht erfolgen. Es waren ~ 9300 Datensätze und 234 Attribute.

Das ursprüngliche Modell war unten und wurde alle in SQL Server 2012 R2 / SDE (7 Minuten über ArcCatalog und 3 Stunden mit Python) ausgeführt:

  1. Löschen Sie Zeilen der Feature-Class in SDE
  2. Erstellen Sie eine XY-Ereignisschicht aus einer Tabelle in SQL Server
  3. An Feature Class in SDE anhängen

Wie ich es geändert habe (10 Sekunden über ArcCatalog und 10 Sekunden über Python): •

  1. Das Werkzeug zum Löschen von Zeilen wurde durch das Werkzeug "Abschneiden" für die GIS-Feature-Class in SDE ersetzt
  2. Exportieren Sie die SQL-Tabelle in eine FGDB auf dem lokalen C-Laufwerk
  3. Erstellen Sie eine XY-Ereignisebene im lokalen Speicher
  4. Feature Class zu Feature Class innerhalb der REA auf dem lokalen C-Laufwerk
  5. DANN FGDB-Feature-Class an SDE anhängen
  6. Beachten Sie, dass sich meine SQL Server-Datenbank auf demselben C-Laufwerk befindet wie meine FGDB. Es kann sich über ein Netzwerk etwas verlangsamen, aber höchstwahrscheinlich immer noch nicht die 3 Stunden, die ich gesehen habe.

Was beim ursprünglichen Modell ein wenig geholfen hat, war das Ersetzen der Datenquellen gemäß der oben empfohlenen Nummer 3. Bei der Ausführung in ArcCatalog wurden 30 Sekunden eingespart. Mit Python rasierte es etwa 20 Minuten. Daher ist es eine Geschwindigkeitsvariable, aber in meinem Fall nicht die wertvollste Variable. Laut den meisten Blogs mag SQL Server es einfach nicht, wenn starke Daten „aus dem Speicher“ geladen werden (dh xy-Ereignisebene erstellen). SQL / SDE scheint das Laden eines tatsächlichen Objekts zu bevorzugen. Dies erklärt, warum meine anderen Ladevorgänge, die ich auf die gleiche Weise mache, 1 Minute dauern, aber das sind nur 1000 Datensätze mit 15 Attributen, so dass ich die Effizienz meiner Modelle nie in Frage gestellt habe, bis diese Ladevorgänge jede Nacht durchgeführt werden mussten. Wie bereits erwähnt, beträgt diese Last 9000 Datensätze mit 236 Attributen.

Dylan Kennard
quelle
0

Das Problem mit der Leistung zwischen 10.0 und 10.1 wurde in den SDE-Bibliotheken auf dem Desktop geändert. Früher haben wir 1.000.000 pro Nacht gepostet und nur 45 Minuten gebraucht, nach einem Software-Update dauerte es fast 24 Stunden. Offensichtlich gibt es kein Problem mit den Daten und nur die Software wurde geändert.

Überprüfen Sie die Version der Geodatabase, um sicherzustellen, dass sie mit der Version des Clients übereinstimmt, auf dem arcpy ausgeführt wird. Wir haben dies ESRI gemeldet, ohne dass ein Fehler gemeldet oder erkannt wurde. Es ist ziemlich offensichtlich und das Problem begann nach 10.0 SP1.

Auch ein anderer Test zum Kopieren / Einfügen ist schneller als ein Anhängen. Versuchen Sie dies ab 10.0 und 10.1, und die Leistung sollte ähnlich sein. Dies beweist, dass beim Anhängen von Geometrien ein Fehler in früheren Versionen auftritt.

user63844
quelle