Beberapa waktu yang lalu, saya menulis fungsi Python cepat untuk mengonversi tabel atribut ke kamus python, di mana kuncinya diambil dari bidang ID unik khusus pengguna (biasanya bidang OID). Selain itu, secara default semua bidang disalin ke kamus, tetapi saya telah menyertakan parameter yang memungkinkan hanya subset ditentukan.
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
Ini berfungsi baik untuk dataset yang relatif kecil, tetapi saya hanya menjalankannya di atas meja yang berisi sekitar 750.000 baris dan 15 bidang - sekitar 100MB dalam file geodatabase. Pada ini, fungsi berjalan jauh lebih lambat daripada yang saya harapkan: sekitar 5-6 menit (dan ini setelah menyalin tabel ke in_memory
ruang kerja). Saya benar-benar ingin menemukan cara untuk mempercepat konversi ke kamus, atau mendapatkan beberapa wawasan tentang strategi yang lebih baik untuk memanipulasi sejumlah besar data atribut menggunakan Python.
UpdateCursors tidak akan berfungsi dengan baik untuk saya, karena ketika satu baris berubah, ia berpotensi memicu perubahan di beberapa baris lainnya. Melewati dan memprosesnya satu per satu terlalu rumit untuk apa yang saya butuhkan.
sumber
subdict = {}
melaluidel subdict
menghasilkan waktu pemrosesan sekitar 10 detik.subdict[field] = row[cursor_fields.index(field)]
lebih cepat daripada meneleponsubdict[field] = row.getValue(field)
. Dalam skenario terakhir Anda akan melakukan satu langkah ... meskipun perbedaan kinerja antara pengindeksan dua daftar (cursor_fields
danrow
) dan menggunakan proses ESRI tunggal mungkin tidak jauh lebih baik dan bahkan mungkin lebih buruk!Jawaban:
Saya pikir masalahnya adalah kemungkinan dua baris Anda di mana Anda pergi ke bidang dan menambahkan setiap bidang secara individual ke
subdict
kamus Anda .row
Objek Anda sudah menjadi tupel dalam urutan yang sama dengan bidang Anda, manfaatkan itu dan gunakanzip
fungsinya.Ini tersendat melalui kelas fitur catatan 218k file 16k geodatabase fitur dalam 8 detik pada sistem saya.
Sunting: Mencoba tes yang lebih keras. Catatan 518k melalui koneksi SDE jarak jauh dengan 16 bidang termasuk OBJECTID dan Shape, dijalankan pada 32-bit. 11 detik :)
sumber
key_field
bidang pertama sehingga saya bisa mengandalkan penggunaanrow[0]
untuk referensi nilaikey_field
. Saya juga harus mengubah variabel Andadict
menjadiattdict
. dict adalah kata kunci, dan tanpa kata kunci itu saya tidak dapat menggunakandict(zip())
arcpy.da
dimaksudkan untuk diaktifkan.