Hace un tiempo, escribí una función rápida de Python para convertir una tabla de atributos en un diccionario de Python, donde la clave se toma de un campo de ID único especificado por el usuario (generalmente el campo OID). Además, de forma predeterminada, todos los campos se copian en el diccionario, pero he incluido un parámetro que permite especificar solo un subconjunto.
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
Esto funciona muy bien para conjuntos de datos relativamente pequeños, pero solo lo ejecuté en una tabla que contiene aproximadamente 750,000 filas y 15 campos, alrededor de 100 MB en una geodatabase de archivos. En estos, la función funciona mucho más lentamente de lo que esperaba: alrededor de 5-6 minutos (y esto es después de copiar la tabla en el in_memory
espacio de trabajo). Realmente me gustaría encontrar una manera de acelerar la conversión al diccionario, u obtener una idea de una mejor estrategia para manipular grandes cantidades de datos de atributos utilizando Python.
UpdateCursors no funcionará bien para mí, porque cuando cambia una fila, tiene el potencial de provocar cambios en varias otras. Recorrerlos y procesarlos uno por uno es demasiado engorroso para lo que necesito.
subdict = {}
través de del subdict
produce un tiempo de procesamiento de aproximadamente 10 segundos.
subdict[field] = row[cursor_fields.index(field)]
son más rápidas que las llamadas subdict[field] = row.getValue(field)
. En el último escenario, estaría realizando un paso ... ¡aunque la diferencia en el rendimiento entre indexar dos listas ( cursor_fields
y row
) y usar un solo proceso de ESRI puede no ser mucho mejor e incluso podría ser peor!