Há um tempo atrás, escrevi uma função rápida do Python para converter uma tabela de atributos em um dicionário python, onde a chave é obtida de um campo de ID exclusivo especificado pelo usuário (normalmente o campo OID). Além disso, por padrão, todos os campos são copiados para o dicionário, mas incluímos um parâmetro que permite especificar apenas um 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
Isso funciona muito bem para conjuntos de dados relativamente pequenos, mas eu apenas o executei em uma tabela contendo cerca de 750.000 linhas e 15 campos - cerca de 100 MB em um geodatabase de arquivo. Nesses, a função é executada muito mais lentamente do que eu esperava: cerca de 5-6 minutos (e isso é depois de copiar a tabela para a área de in_memory
trabalho). Eu realmente gostaria de encontrar uma maneira de acelerar a conversão em dicionário ou obter algumas dicas sobre uma estratégia melhor para manipular grandes quantidades de dados de atributos usando Python.
UpdateCursors não funcionará bem para mim, porque quando uma linha é alterada, ela pode causar alterações em várias outras. Fazer um loop e processá-los um de cada vez é muito complicado para o que eu preciso.
subdict = {}
através del subdict
produz um tempo de processamento de cerca de 10 segundos.
subdict[field] = row[cursor_fields.index(field)]
é mais rápida do que a chamada subdict[field] = row.getValue(field)
. No último cenário, você executaria uma etapa ... embora a diferença de desempenho entre a indexação de duas listas ( cursor_fields
e row
) e o uso de um único processo ESRI possa não ser muito melhor e apenas pior!