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_memoryespacio 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.
fuente

subdict = {}través dedel subdictproduce un tiempo de procesamiento de aproximadamente 10 segundos.subdict[field] = row[cursor_fields.index(field)]son más rápidas que las llamadassubdict[field] = row.getValue(field). En el último escenario, estaría realizando un paso ... ¡aunque la diferencia en el rendimiento entre indexar dos listas (cursor_fieldsyrow) y usar un solo proceso de ESRI puede no ser mucho mejor e incluso podría ser peor!Respuestas:
Creo que el problema es probablemente sus dos líneas donde va sobre los campos y agrega cada campo individualmente a su
subdictdiccionario.Su
rowobjeto ya es una tupla en el mismo orden que sus campos, aproveche eso y use lazipfunción.Esto atravesó una clase de entidad de geodatabase de archivos de campo de registro de 218k en 8 segundos en 8 segundos en mi sistema.
Editar: Intenté una prueba más rigurosa. Los registros de 518k en una conexión SDE remota con 16 campos, incluidos OBJECTID y Shape, se ejecutan a 32 bits. 11 segundos :)
fuente
key_fieldel primer campo para poder confiar en el usorow[0]para hacer referencia al valor dekey_field. También tuve que cambiar tu variabledictaattdict. dict es una palabra clave, y sin esa palabra clave que no podía usardict(zip())arcpy.daestá destinado a habilitar.