Python ile öznitelik tablolarını değiştirmek için en hızlı yöntemler?


12

Bir süre önce, bir öznitelik tablosunu python sözlüğüne dönüştürmek için hızlı bir Python işlevi yazdım, burada anahtar kullanıcı tarafından belirtilen benzersiz bir kimlik alanından (genellikle OID alanı) alınır. Ayrıca, varsayılan olarak tüm alanlar sözlüğe kopyalanır, ancak yalnızca bir alt kümenin belirtilmesine izin veren bir parametre ekledim.

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

Bu nispeten küçük veri kümeleri için harika çalışıyor, ancak sadece yaklaşık 750.000 satır ve 15 alan içeren bir tabloda çalıştırdım - bir dosya coğrafi veritabanında yaklaşık 100 MB. Bunlarda, işlev beklediğimden çok daha yavaş çalışır: yaklaşık 5-6 dakika (ve bu tabloyu in_memoryçalışma alanına kopyaladıktan sonra ). Sözlüğe dönüşümü hızlandırmanın bir yolunu bulmak veya Python kullanarak büyük miktarda özellik verilerini işlemek için daha iyi bir strateji hakkında biraz bilgi edinmek istiyorum.

UpdateCursors benim için iyi çalışmaz, çünkü bir satır değiştiğinde, diğerlerinde değişiklikleri tetikleme potansiyeline sahiptir. Bir kerede bir döngü yapmak ve işlemek ihtiyacım olan şey için çok hantal.


2
Komut dosyanızı ne kadar optimize edebileceğinizi sınırlayan faktör, imlecinizi yinelemek için geçen süre olabilir. Sözlüklerinizi oluşturmadan imleci tekrarlamak için geçen süreyi karşılaştırdınız mı?
Jason

2
@Jason satırları baştan subdict = {}sona yorumlamak del subdictyaklaşık 10 saniyelik bir işlem süresi sağlar.
nmpeterson

Muhtemelen benden daha fazlasını biliyorsunuzdur, ancak optimizasyon açısından sunacağım tek şey, aramanın aramadan subdict[field] = row[cursor_fields.index(field)]daha hızlı olup olmadığına bakmaktır subdict[field] = row.getValue(field). İkinci senaryoda, bir adım gerçekleştiriyor olacaksınız ... ancak iki listeyi indeksleme ( cursor_fieldsve row) ve tek bir ESRI işlemi kullanma arasındaki performans farkı çok daha iyi olmayabilir ve daha da kötü olabilir!
Jason

Yanıtlar:


16

Bence sorun muhtemelen alanların üzerinden gittiğiniz ve her alanı subdictsözlüğünüze ayrı ayrı eklediğiniz iki satırınızdır .

for field in valid_fields:
    subdict[field] = row[cursor_fields.index(field)]

Sizin rownesne o yararlanmak ve kullanmak, zaten alanlar aynı sırada bir başlık olur zipişlevi.

def make_attribute_dict(fc, key_field, attr_list=['*']):
    attdict = {}
    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]
    #Ensure that key_field is always the first field in the field list
    cursor_fields = [key_field] + list(set(valid_fields) - set([key_field]))
    with arcpy.da.SearchCursor(fc, cursor_fields) as cursor:
        for row in cursor:
            attdict[row[0]] = dict(zip(cursor.fields,row))
    return attdict

Bu, sistemimde 8 saniyede 218k kayıt 16 alan dosyası geodatabase özellik sınıfından çekildi.

Düzenleme: Daha titiz bir test denedi. OBJECTID ve Shape dahil 16 alanlı 32k'de çalışan uzak SDE bağlantısı üzerinden 518k kayıt. 11 saniye :)


1
Ben değerine başvurmak key_fieldiçin kullanarak güvenebilirsiniz böylece ilk alanı yaptığımı unutmayın . Ben de Değişkeninizi değiştirmek zorunda için . dict bir anahtar kelime ve bu anahtar kelime olmadan kullanamadımrow[0]key_fielddictattdictdict(zip())
blord-castillo

6
Zeki. Bu tam arcpy.daolarak etkinleştirilmesi gereken tatlı deyimsel Python türüdür .
Jason Scheirer

İyi fikir. Yöntemi seviyorum ve gerçekten yardımcı oldu.
nmpeterson
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.