Jakiś czas temu napisałem szybką funkcję Pythona do konwertowania tabeli atrybutów na słownik Pythona, w której klucz jest pobierany z unikalnego pola identyfikatora określonego przez użytkownika (zazwyczaj pola OID). Dodatkowo domyślnie wszystkie pola są kopiowane do słownika, ale zawarłem parametr pozwalający na określenie tylko podzestawu.
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
Działa to świetnie w przypadku stosunkowo małych zestawów danych, ale właśnie uruchomiłem go na tabeli zawierającej około 750 000 wierszy i 15 pól - około 100 MB w geobazie pliku. Na nich funkcja działa znacznie wolniej, niż się spodziewałam: około 5-6 minut (i to po skopiowaniu tabeli do in_memory
obszaru roboczego). Naprawdę chciałbym znaleźć sposób na przyspieszenie konwersji na słownik lub uzyskać lepszy wgląd w lepszą strategię manipulowania dużą ilością danych atrybutów za pomocą Pythona.
UpdateCursors nie będzie dla mnie działał dobrze, ponieważ gdy zmienia się jeden wiersz, może on wywołać zmiany w kilku innych. Pętlowanie i przetwarzanie ich pojedynczo jest zbyt kłopotliwe dla tego, czego potrzebuję.
źródło
subdict = {}
do,del subdict
daje czas przetwarzania około 10 sekund.subdict[field] = row[cursor_fields.index(field)]
jest szybsze niż dzwonieniesubdict[field] = row.getValue(field)
. W tym drugim scenariuszu wykonujesz jeden krok ... chociaż różnica w wydajności między indeksowaniem dwóch list (cursor_fields
irow
) a użyciem pojedynczego procesu ESRI może nie być znacznie lepsza, a może nawet gorsza!Odpowiedzi:
Myślę, że problemem są prawdopodobnie dwie linie, w których przechodzisz nad polami i dołączasz każde pole osobno do
subdict
słownika.Twój
row
obiekt jest już krotką w tej samej kolejności co twoje pola, skorzystaj z tego i użyjzip
funkcji.Spowodowało to przeszukanie klasy obiektów geobazy danych z 16 polowymi rekordami i 16 polami w 8 sekund w moim systemie.
Edycja: Wypróbowałem bardziej rygorystyczny test. 518k rekordów przez zdalne połączenie SDE z 16 polami, w tym OBJECTID i Shape, działającymi w wersji 32-bitowej 11 sekund :)
źródło
key_field
pierwsze pole, aby móc polegać na używaniurow[0]
do odwoływania się do wartościkey_field
. Musiałem także zmienić twoją zmiennądict
naattdict
. dict jest słowem kluczowym i bez tego słowa kluczowego nie byłbym w stanie użyćdict(zip())
arcpy.da
ma umożliwić.