Verwenden von arcgis desktop 10.3.1 Ich habe ein Skript, das einen Suchcursor verwendet, um Werte an eine Liste anzuhängen, und dann min () verwendet, um die kleinste Ganzzahl zu finden. Die Variable wird dann in einem Skript verwendet. Die Feature-Class hat 200.000 Zeilen und die Fertigstellung des Skripts dauert sehr lange. Gibt es eine Möglichkeit, dies schneller zu tun? Im Moment denke ich, ich würde es einfach von Hand machen, anstatt ein Skript zu schreiben, da es so lange dauert.
import arcpy
fc = arcpy.env.workspace = arcpy.GetParameterAsText(0)
Xfield = "XKoordInt"
cursor = arcpy.SearchCursor(fc)
ListVal = []
for row in cursor:
ListVal.append(row.getValue(Xfield))
value = min(ListVal)-20
print value
expression = "(!XKoordInt!-{0})/20".format(value)
arcpy.CalculateField_management (fc, "Matrix_Z" ,expression, "PYTHON")
arcpy.Statistics_analysis
? desktop.arcgis.com/de/arcmap/10.3/tools/analysis-toolbox/…min_val = min([i[0] for i in arcpy.da.SearchCursor(fc,Xfield)])
Antworten:
Ich kann verschiedene Dinge sehen, die dazu führen können, dass Ihr Skript langsam ist. Die Sache, die wahrscheinlich sehr langsam ist, ist die
arcpy.CalculateField_management()
Funktion. Sie sollten einen Cursor verwenden, er wird um einige Größenordnungen schneller. Sie sagten auch, dass Sie ArcGIS Desktop 10.3.1 verwenden, aber Sie verwenden die alten Cursor im ArcGIS 10.0-Stil, die ebenfalls viel langsamer sind.Die min () -Operation selbst auf einer Liste von 200 KB ist ziemlich schnell. Sie können dies überprüfen, indem Sie dieses kleine Snippet ausführen. es passiert im Handumdrehen:
Sehen Sie, ob dies schneller geht:
BEARBEITEN:
Ich habe einige Timing-Tests durchgeführt und wie ich vermutet habe, hat der Feldrechner fast doppelt so lange gedauert wie der neue Stilcursor. Interessanterweise war der Cursor im alten Stil ~ 3x langsamer als der Feldrechner. Ich habe 200.000 zufällige Punkte erstellt und dieselben Feldnamen verwendet.
Eine Dekorationsfunktion wurde verwendet, um jede Funktion zeitlich zu steuern (dies kann zu einem geringfügigen Aufwand beim Einrichten und Herunterfahren von Funktionen führen, sodass das Timeit- Modul möglicherweise etwas genauer ist, um Snippets zu testen).
Hier sind die Ergebnisse:
Und hier ist der Code, den ich verwendet habe (alles in einzelne Funktionen unterteilt, um den
timeit
Dekorator zu verwenden):Und schließlich war dies der eigentliche Ausdruck von meiner Konsole.
Edit 2: Ich habe gerade einige aktualisierte Tests gepostet und einen kleinen Fehler in meiner
timeit
Funktion festgestellt .quelle
"XKoordInt"
. Siehe meine Bearbeitung, alles was Sie tun müssen, ist Nullen zu überspringen.range
. ArcGIS verwendet weiterhin Python 2.7, daher wird a zurückgegebenlist
. Aber in 3.xrange
ist es eine eigene Art von Objekt, das Optimierungen haben kann. Ein zuverlässigerer Test wäremin(list(range(200000)))
, der sicherstellen würde, dass Sie mit einer einfachen Liste arbeiten. Verwenden Sie dastimeit
Modul auch für Leistungstests.Wie @crmackey hervorhebt, ist der langsame Teil wahrscheinlich auf die Berechnungsfeldmethode zurückzuführen. Alternativ zu den anderen geeigneten Lösungen und unter der Annahme, dass Sie eine Geodatabase zum Speichern Ihrer Daten verwenden, können Sie den Befehl Order By sql verwenden, um in aufsteigender Reihenfolge zu sortieren, bevor Sie den Aktualisierungscursor ausführen.
In diesem Fall entfernt die where-Klausel die Nullen, bevor die Abfrage ausgeführt wird, oder Sie können das andere Beispiel verwenden, das vor dem Aktualisieren nach None sucht.
quelle
min()
. Ich werde dies auch in meine Geschwindigkeitstests einbeziehen, um den Leistungsgewinn zu zeigen.0.56
Sekunden ausgeführt, was nicht so viel Leistungsgewinn bedeutet, wie ich erwartet hätte.In solchen Fällen können Sie auch numpy verwenden, obwohl dies speicherintensiver ist.
Sie erhalten immer noch einen Flaschenhals, wenn Sie die Daten in ein Numpy-Array und dann wieder in die Datenquelle laden. Ich habe jedoch festgestellt, dass der Leistungsunterschied bei größeren Datenquellen besser ist (zugunsten von Numpy), insbesondere wenn Sie mehrere benötigen Statistiken / Berechnungen.:
quelle
Warum nicht die Tabelle aufsteigend sortieren und dann mit einem Suchcursor den Wert für die erste Zeile ermitteln? http://pro.arcgis.com/de/pro-app/tool-reference/data-management/sort.htm
quelle
Ich würde das
SearchCursor
in einen Generatorausdruck (dhmin()
) für Geschwindigkeit und Prägnanz einwickeln . Fügen Sie dann den Mindestwert aus dem Generatorausdruck in einenda
Typ einUpdateCursor
. So etwas wie das Folgende:quelle
SearchCursor
nicht geschlossen werden, wenn Sie damit fertig sind?In Ihrer Schleife befinden sich zwei Funktionsreferenzen, die für jede Iteration neu bewertet werden.
for row in cursor: ListVal.append(row.getValue(Xfield))
Es sollte schneller (aber etwas komplexer) sein, die Referenzen außerhalb der Schleife zu haben:
quelle
append()
Methode deslist
Datentyps. Ich glaube nicht, dass hier sein Engpass passiert, ich würde wetten, dass die Berechnungsfeldfunktion der Schuldige ist. Dies kann überprüft werden, indem der Feldrechner mit einem neuen Stilcursor verglichen wird.