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.
fonte
subdict = {}
atravésdel subdict
produz um tempo de processamento de cerca de 10 segundos.subdict[field] = row[cursor_fields.index(field)]
é mais rápida do que a chamadasubdict[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
erow
) e o uso de um único processo ESRI possa não ser muito melhor e apenas pior!Respostas:
Acho que o problema é provavelmente suas duas linhas em que você está passando os campos e acrescentando cada campo individualmente ao seu
subdict
dicionário.Seu
row
objeto já é uma tupla na mesma ordem que seus campos, aproveite isso e use azip
funçãoIsso resultou em uma classe de recursos de geodatabase de 218k registros e 16 campos em 8 segundos no meu sistema.
Edit: Tentei um teste mais rigoroso. 518k registros em uma conexão SDE remota com 16 campos, incluindo OBJECTID e Shape, são executados em 32 bits. 11 segundos :)
fonte
key_field
o primeiro campo para poder usar orow[0]
para referenciar o valor dekey_field
. Eu também tive que mudar sua variáveldict
paraattdict
. dict é uma palavra-chave, e sem a palavra-chave que eu não poderia usardict(zip())
arcpy.da
se destina a ativar.