Il y a quelque temps, j'ai écrit une fonction Python rapide pour convertir une table d'attributs en un dictionnaire Python, où la clé est extraite d'un champ ID unique spécifié par l'utilisateur (généralement le champ OID). De plus, par défaut, tous les champs sont copiés dans le dictionnaire, mais j'ai inclus un paramètre permettant de spécifier uniquement un sous-ensemble.
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
Cela fonctionne très bien pour des ensembles de données relativement petits, mais je viens de l'exécuter sur une table contenant environ 750 000 lignes et 15 champs - environ 100 Mo dans une géodatabase fichier. Sur ceux-ci, la fonction s'exécute beaucoup plus lentement que ce à quoi je m'attendais: environ 5-6 minutes (et c'est après avoir copié la table dans l' in_memory
espace de travail). J'aimerais vraiment trouver un moyen d'accélérer la conversion en dictionnaire, ou obtenir un aperçu d'une meilleure stratégie pour manipuler de grandes quantités de données d'attributs à l'aide de Python.
UpdateCursors ne fonctionnera pas bien pour moi, car lorsqu'une ligne change, elle a le potentiel de déclencher des changements dans plusieurs autres. Les parcourir et les traiter un par un est trop lourd pour ce dont j'ai besoin.
subdict = {}
part del subdict
donne un temps de traitement d'environ 10 secondes.
subdict[field] = row[cursor_fields.index(field)]
est plus rapide que l'appel subdict[field] = row.getValue(field)
. Dans ce dernier scénario, vous effectuez une étape ... bien que la différence de performances entre l'indexation de deux listes ( cursor_fields
et row
) et l'utilisation d'un seul processus ESRI ne soit pas beaucoup mieux et pourrait même être pire!