Некоторое время назад я написал быструю функцию Python для преобразования таблицы атрибутов в словарь Python, где ключ берется из указанного пользователем поля уникального идентификатора (обычно это поле OID). Кроме того, по умолчанию все поля копируются в словарь, но я включил параметр, позволяющий указать только подмножество.
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
Это прекрасно работает для сравнительно небольших наборов данных, но я просто запустил его на таблице, содержащей около 750 000 строк и 15 полей - около 100 МБ в файловой базе геоданных. На них функция работает намного медленнее, чем я ожидал: около 5-6 минут (и это после копирования таблицы в in_memory
рабочую область). Я действительно хотел бы найти способ ускорить преобразование в словарь или получить представление о лучшей стратегии для манипулирования большими объемами данных атрибутов с использованием Python.
UpdateCursors не будут работать хорошо для меня, потому что, когда одна строка изменяется, она может вызвать изменения в нескольких других. Перебирать и обрабатывать их по одному слишком громоздко для того, что мне нужно.
источник
subdict = {}
сквозного,del subdict
дает время обработки около 10 секунд.subdict[field] = row[cursor_fields.index(field)]
быстрее ли вызов, чем вызовsubdict[field] = row.getValue(field)
. В последнем сценарии вы выполняете один шаг ... хотя разница в производительности между индексированием двух списков (cursor_fields
иrow
) и использованием одного процесса ESRI может быть не намного лучше, а может быть, даже хуже!Ответы:
Я думаю, что проблема, скорее всего, в ваших двух строках, где вы перебираете поля и добавляете каждое поле отдельно в свой
subdict
словарь.Ваш
row
объект уже является кортежем в том же порядке, что и ваши поля, воспользуйтесь этим и используйтеzip
функцию.Это провалилось через 88 секунд в моей системе через 218 тыс. Записей файлового класса базы геоданных.
Изменить: попробовал более строгий тест. 518k записей по удаленному соединению SDE с 16 полями, включая OBJECTID и Shape, работающими в 32-битном режиме. 11 секунд :)
источник
key_field
первое поле, чтобы можно было использоватьrow[0]
для ссылки на значениеkey_field
. Я также должен был изменить вашу переменнуюdict
наattdict
. dict - это ключевое слово, и без этого ключевого слова я бы не смог воспользоватьсяdict(zip())
arcpy.da
предназначен для включения.