Vor einiger Zeit habe ich eine schnelle Python-Funktion zum Konvertieren einer Attributtabelle in ein Python-Wörterbuch geschrieben, bei der der Schlüssel einem benutzerdefinierten eindeutigen ID-Feld entnommen wird (normalerweise dem OID-Feld). Außerdem werden standardmäßig alle Felder in das Wörterbuch kopiert, aber ich habe einen Parameter eingefügt, mit dem nur eine Teilmenge angegeben werden kann.
def make_attribute_dict(fc, key_field, attr_list=['*']):
dict = {}
fc_field_objects = arcpy.ListFields(fc)
fc_fields = [field.name for field in fc_field_objects if field.type != 'Geometry']
if attr_list == ['*']:
valid_fields = fc_fields
else:
valid_fields = [field for field in attr_list if field in fc_fields]
if key_field not in valid_fields:
cursor_fields = valid_fields + [key_field]
else:
cursor_fields = valid_fields
with arcpy.da.SearchCursor(fc, cursor_fields) as cursor:
for row in cursor:
key = row[cursor_fields.index(key_field)]
subdict = {}
for field in valid_fields:
subdict[field] = row[cursor_fields.index(field)]
dict[key] = subdict
del subdict
return dict
Dies funktioniert hervorragend für relativ kleine Datasets, aber ich habe es gerade für eine Tabelle ausgeführt, die ungefähr 750.000 Zeilen und 15 Felder enthält - ungefähr 100 MB in einer File-Geodatabase. Auf diesen läuft die Funktion viel langsamer als ich erwartet hätte: ungefähr 5-6 Minuten (und dies ist nach dem Kopieren der Tabelle in den in_memory
Arbeitsbereich). Ich möchte wirklich einen Weg finden, um die Konvertierung in ein Wörterbuch zu beschleunigen, oder einen Einblick in eine bessere Strategie für die Bearbeitung großer Mengen von Attributdaten mit Python erhalten.
UpdateCursors funktioniert bei mir nicht gut, da bei Änderungen an einer Zeile möglicherweise Änderungen an mehreren anderen Zeilen ausgelöst werden. Es ist zu umständlich, sie nacheinander durchzugehen und zu verarbeiten, als dass ich das benötige.
subdict = {}
bis auskommentiert, del subdict
ergibt eine Verarbeitungszeit von etwa 10 Sekunden.
subdict[field] = row[cursor_fields.index(field)]
schneller ist als das Anrufen subdict[field] = row.getValue(field)
. Im letzteren Szenario würden Sie einen Schritt ausführen ... obwohl der Unterschied in der Leistung zwischen der Indizierung von zwei Listen ( cursor_fields
und row
) und der Verwendung eines einzelnen ESRI-Prozesses möglicherweise nicht viel besser und möglicherweise sogar noch schlechter ist!