ArcPy betiği neden yavaş?


12

İçinde çokgen özelliği bilgi ile bir nokta shapefile bir alanı güncelleştirmek için basit bir arcpy komut dosyası var. Arcpy'de 100 puan yapmak 9 dakika sürer, ancak arcmap'deki uzamsal birleşme anlıktır. Eminim bu sorunu çözmenin hızlı bir yolu vardır. Birisi beni doğru yönde gösterebilir mi?

import took 0:00:07.085000
extent took 0:00:05.991000
one pt loop took 0:00:03.780000
one pt loop took 0:00:03.850000
one pt loop took 0:00:03.791000


import datetime
t1 = datetime.datetime.now()
import arcpy
t2 = datetime.datetime.now()
print "import took %s" %  ( t2-t1)
#set up environment
arcpy.env.workspace = "data\\"
arcpy.env.overwriteOutput = True

desc = arcpy.Describe("parcels.shp")
ext = desc.Extent
extent = (ext.XMin,ext.XMax,ext.YMin,ext.YMax)
t3 = datetime.datetime.now()
print "extent took %s" %  (t3 -t2)
fc = arcpy.CreateRandomPoints_management("", "malls.shp", "", ext, 100, "", "POINT", "")
arcpy.AddField_management("malls.shp", 'ParcelID', 'LONG')

rows = arcpy.UpdateCursor('malls.shp',"","",'ParcelID')
for row in rows:
    t4 = datetime.datetime.now()
    pt = row.Shape.getPart()
    for polyrow in arcpy.SearchCursor('parcels.shp'):
        t6 = datetime.datetime.now()
        poly = polyrow.getValue('Shape')
        if extent[0]<pt.X<extent[1] and extent[2]<pt.Y<extent[3]:
            if poly.contains(pt):
                print "works"
                row.ParcelID = polyrow.Parcels_ID
                rows.updateRow(row)
                break #we can stop looking for matches since
        t7 = datetime.datetime.now()
        "a full poly loop took %s" % (t7-t6)
    t5 = datetime.datetime.now()
    print "one pt loop took %s" % (t5-t4)


print datetime.datetime.now() -t1

4
Hangi ArcGIS versiyonundasınız? 10.1 arcpy.da(Veri Erişimi) modülünü imleçlerin (çok) daha hızlı sürümleriyle ekledi .
blah238

Yanıtlar:


20

İçin ikinci bir imleç oluşturmanız gerekirse parcels.shp, bunu ilk imleciniz için döngü dışında yapın. Durduğu gibi, komut dosyanız her satır için yeni bir imleç nesnesi oluşturuyor ve malls.shpbu da tüm bu işlem süresine mal oluyor.

...
rows = arcpy.UpdateCursor('malls.shp',"","",'ParcelID')
polyrows = arcpy.SearchCursor('parcels.shp')
for row in rows:
    t4 = datetime.datetime.now()
    pt = row.Shape.getPart()
    for polyrow in polyrows:
...

Aynen öyleydi. Teşekkür ederim. ve sonra her geçmek istediğimde ikinci imlecimde .reset () kullanıyorum? Görünüşe göre şimdi sadece 1 kez imleçten geçiyor.
EmdyP

Hmm, satırları sıfırlamanız gerekmez. Komut dosyasının sonunda hem satır nesnelerini hem de imleç nesnelerini sildiğinizden emin olun. Yapmazsan komik şeyler olabilir.
Jason

Ben iç döngünün imleç düşünüyorum yapar Eğer bu yol giderseniz her zaman sıfırlanır gereğini. Bir alternatif için cevabımı görün.
blah238

10

@ Jason'ın cevabı (ve orijinal yaklaşımınız) ile ilgili problem , mekansal endeksten faydalanmaması ve nokta sayısı arttıkça katlanarak daha yavaş olacak iç içe, iki imleçli bir döngü gerektirmesidir.

Nokta özelliği sınıfını yerinde güncellemenize izin verirken daha hızlı olabilecek alternatif bir iş akışı (Uzamsal Birleştirme, yalnızca yeni bir özellik sınıfı çıkarır, var olanı güncelleştirmez) şunlar olabilir:

  1. Bir ara (belki de bellek içi) özellik sınıfı oluşturmak için Uzamsal Birleştirme kullanın
  2. Ara özellik sınıfını mevcut nokta özellik sınıfınıza katılmak için Katıl Ekle'yi kullanın
  3. Kullanım hesaplayın Tarla veya UpdateCursor mevcut noktası özelliği sınıfında alanına katılmış alanındaki değerleri kopyalamak için.

2
Bu alternatif iş akışını seviyorum - Soruyu sormasam bile, burada bir şeyler yapmanın yeni yollarını öğreniyorum.
Jason
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.