Büyük Veri için Python Kodunu Düzenleme


34

Aşağıdaki iş akışı boyunca şekil alanlarını almak için tasarlanmış Python kodum var:

  1. Birleştirme noktaları
  2. Noktaları birleştirin, böylece birbirinden 1 m uzaklıktaki herhangi bir nokta bir nokta haline gelir
  3. Z <10 olan noktaların seçili olduğu Özellik katmanı oluştur
  4. Tampon Noktaları
  5. Çokgenden rastere 1m çözünürlük
  6. Yeniden sınıflandırma, burada 1 - 9 = 1; NoData = 0

Her şekil dosyası ~ 5x7 km'yi kapsayan yaklaşık 250.000 ila 350.000 noktaya sahiptir. Giriş olarak kullanılan nokta verileri, ağaç konumlarını temsil eder. Her nokta (yani ağaç), taç yarıçapını temsil eden ve tampon işleminde kullanılan ilişkili bir "z" değerine sahiptir. Niyetim, nihai ikili çıktıyı, gölgelik kapağını tanımlayan bir raster üretmek için ayrı bir işlemde kullanmaktır.

Dört şekil dosyasıyla bir test yaptım ve 700 MB raster üretti ve 35 dakika sürdü (i5 işlemci ve 8 GB RAM). Bu işlemi 3500 form dosyasında çalıştırmam gerekeceğini görünce, süreci kolaylaştırmak için herhangi bir tavsiyede bulunmak isterim (ekli koda bakınız). Genel olarak konuşursak, coğrafi işlem yapan büyük verilerle başa çıkmanın en iyi yolu nedir? Daha spesifik olarak, verimliliği arttırmaya yardımcı olabilecek kodda veya iş akışında herhangi bir değişiklik var mı?

Düzenle :

Coğrafi işleme görevleri için süre (toplamın% 'si):

  • Birleştirme =% 7.6
  • Entegre =% 7.1
  • Lyr özelliği = 0
  • Tampon =% 8,8
  • Poli-Raster = % 74,8
  • Yeniden sınıflandırma =% 1.6

görüntü tanımını buraya girin

# Import arcpy module
import arcpy

# Check out any necessary licenses
arcpy.CheckOutExtension("spatial")

# Script arguments
temp4 = arcpy.GetParameterAsText(0)
if temp4 == '#' or not temp4:
    temp4 = "C:\\gdrive\\temp\\temp4" # provide a default value if unspecified

Reclassification = arcpy.GetParameterAsText(1)
if Reclassification == '#' or not Reclassification:
    Reclassification = "1 9 1;NODATA 0" # provide a default value if unspecified

Multiple_Value = arcpy.GetParameterAsText(2)
if Multiple_Value == '#' or not Multiple_Value:
    Multiple_Value = "C:\\t1.shp;C:\\t2.shp;C:\\t3.shp;C:\\t4.shp" # provide a default value if unspecified

# Local variables:
temp_shp = Multiple_Value
Output_Features = temp_shp
temp2_Layer = Output_Features
temp_Buffer = temp2_Layer
temp3 = temp_Buffer

# Process: Merge
arcpy.Merge_management(Multiple_Value, temp_shp, "x \"x\" true true false 19 Double 0 0 ,First,#,C:\\#########omitted to save space

# Process: Integrate
arcpy.Integrate_management("C:\\gdrive\\temp\\temp.shp #", "1 Meters")

# Process: Make Feature Layer
arcpy.MakeFeatureLayer_management(temp_shp, temp2_Layer, "z <10", "", "x x VISIBLE NONE;y y VISIBLE NONE;z z VISIBLE NONE;Buffer Buffer VISIBLE NONE")

# Process: Buffer
arcpy.Buffer_analysis(temp2_Layer, temp_Buffer, "z", "FULL", "ROUND", "NONE", "")

# Process: Polygon to Raster
arcpy.PolygonToRaster_conversion(temp_Buffer, "BUFF_DIST", temp3, "CELL_CENTER", "NONE", "1")

# Process: Reclassify
arcpy.gp.Reclassify_sa(temp3, "Value", Reclassification, temp4, "DATA")

3
Zamanın büyüklüğünün bir veya birkaç adıma geçip geçmediğini belirlemek için bazı performans zamanlama kodlarını koymak faydalı olabilir - böylece performans artışlarını denemek ve bulmak için odaklanmaları mümkündür
PolyGeo

5
ArcPy kullanmaya devam ederseniz, performansı artırmak için pek çok seçeneğiniz olduğunu sanmıyorum. Belki bunu yapmak için diğer araçlara bakabilirsiniz? FME veya belki postgis gibi araçlar?
tmske

3
Hangi piksel türünün kullanıldığı belli değil, ancak "Bayt" (olması gerektiği) ise, ham veri depolaması raster başına 5000x7000 = 35Mb (~ 33.4MB) olacaktır, bu aslında büyük değildir. Bununla birlikte, bir sonraki 3500 ebatı (zaman ebatı?) Toplam ham ebadı ~ 114 GB'ye yükseltir.
Mike T

5
Bu tarifnameden algoritmanın ne yaptığını (ya da yapmayı amaçladığını) söyleyemesem de, çoğu durumda nokta tamponları tarafından takip edilen nokta tamponları, noktaların rasterleştirilmesi ve ardından bir odak istatistiği (genellikle ortalama veya toplam) ile değiştirilmelidir. Sonuç aynı olacak, ancak uzun tamponlama ve poli rasterleştirme adımlarından kaçınılarak çok daha hızlı bir şekilde elde edilecektir . Ben (kuvvetli bir şekilde) önemli ek hızlandırmalar elde edilebileceğinden şüpheliyim, ancak prosedürün açıklamasının belirsizliğinden dolayı özel bir tavsiyede bulunamıyorum.
whuber

2
Noktaların etrafındaki tamponlar değişken boyuttadır (noktanın z değerine bağlı olarak). Bence hala odak istatistiklerini yapmak için, sonuç noktalarını z değerine göre ayırmanız ve her sette raster ve odak istatistiklerini yapmanız gerekir (stat'ı maksimum olan dairesel bir mahallede yarıçap olarak z kullanarak). Ardından sonuçları bir araya getirmek için Hücre İstatistikleri'ni 9 rasterin hepsinde maksimum stat ile çalıştırın. (Bu hala muhtemelen tampondan çok daha hızlıdır ve büyük bir veri kümesiyle rasterleştirilir.)
blord-castillo

Yanıtlar:


10

Size yardımcı olması gereken bazı algoritma değişiklikleri.

Seçiminizi birleştirme veya bütünleştirme işleminden önce uygulayın. Bu, en pahalı olan fonksiyonlar için önemli ölçüde azalır.

Birleştirme ve entegrasyon hem hafıza pahalıdır, bu yüzden özellik sınıflarına getirdiğiniz gibi özelliklerden kurtulmaya devam etmek ve birleştirme ve bütünleşmelerin boyutunu korumak için birleştirmelerinizi ikili bir ağaçta yapmayı denemek istersiniz. örneğin dört şekil dosyası için iki şekil dosyasını birleştirir ve birleştirirsiniz; iki şekil dosyasını daha birleştirin ve birleştirin; sonuçta ortaya çıkan iki özellik sınıfını birleştirip bütünleştirin.

İş kuyruğunuz, shapefile başvuruları kuyruğu olarak başlar. Ayrıca sonuçları yerleştirmek için bir sonuç sıranız var. Paralel işleme çalışanınız için run () yöntemi şu işlemleri yapar: Sıradaki iki öğeyi alın. Hiçbir öğe alınmazsa (sıra boş) çalışanı sonlandırın. Bir öğe alınırsa, o öğeyi doğrudan sonuç sırasına koyun.

İki öğe alınırsa, her öğe için: eğer bir biçim dosyasıysa, z <10 için seçin ve bir in_memory özellik sınıfı oluşturun; Aksi halde, zaten bir in_memory özellik sınıfıdır ve seçim adımını atlar. Yeni bir in_memory özellik sınıfı oluşturmak için iki in_memory özellik sınıfını birleştirin. Orijinal iki özellik sınıfını silin. Yeni özellik sınıfında integralini yürütün. Bu özellik sınıfını sonuç sırasına yerleştirin.

Sonra bir while döngüsünü çalıştır. Döngü, shapefile kuyruğuyla başlar ve 1'den büyük uzunluk test eder. Daha sonra kuyruğu işçilerden geçirir. Sonuç kuyruğunun 1'den büyük bir uzunluğu varsa, while döngüsü, sonuç kuyruğu 1 in_memory özellik sınıfına gelinceye kadar işçilerin içinden geçen bir başka paralel işlem yürütür.

Örneğin, 3500 şekil dosyasıyla başlarsanız, ilk sıranızda 3500 iş olacaktır. İkincisi 1750 iş olacak. 875, 438, 219, 110, 55, 28, 14, 7, 4, 2, 1. Büyük tıkanıklığınız hafıza olacak. Yeterli belleğiniz yoksa (ve eğer öyleyse, ilk sonuç kuyruğunun oluşturulmasında bellek tükenirse), o zaman algoritmayı bir kerede 2'den fazla özellik sınıfından sonra birleştirecek şekilde değiştirin; daha uzun işlem süresi karşılığında ilk sonuç sıranızın boyutu. İsteğe bağlı olarak, çıktı dosyalarını yazabilir ve in_memory özellik sınıflarını kullanarak atlayabilirsiniz. Bu önemli ölçüde sizi yavaşlatır, ancak hafıza darboğazı geçmiş olur.

Sadece tüm şekil dosyalarının bir birleştirme ve entegrasyonunu yaptıktan sonra, tek bir özellik sınıfıyla sona erdikten sonra, arabellek, poli-raster ve yeniden sınıflandırma işlemini gerçekleştirirsiniz. Bu şekilde, bu üç işlem yalnızca bir kez gerçekleştirilir ve geometrinizi basit tutarsınız.


Verileriniz belleğe sığacaksa , in_memory çalışma alanını kullanmak için +1 . Coğrafi işlem operasyonlarını önemli ölçüde hızlandırır.
RyanDalton

Bu iyi şeyler. Bir şema ve bazı psuedocode (veya gerçek kod!) İle daha iyi olabileceğini düşünüyorum.
blah238

Evet, kodlamak için biraz zaman ayırmak isterdim. Zaten yeni bir paralel işleme demo betiği yazmam gerekiyor.
blord-castillo

14

Yapacağım ilk şey , CPU - bellek veya IO'ya bağlı olup olmadığınızı hissetmek için Windows 7'de Kaynak Monitörü veya Vista / XP'de perfmon gibi bir sistem kullanarak sisteminizin kaynak kullanımını izlemektir .

Bellek veya IO bağlıysanız, donanımı yükseltmek, sorun boyutunu azaltmak veya yaklaşımı tamamen değiştirmek yerine, yapabileceğiniz çok az şey vardır.

İşlemcinize bağlı olduğunuzu belirlerseniz , işlemlerinizi hızlandırmak için daha fazla CPU çekirdeği kullanıp kullanamayacağınızı görmek için multiprocessingmodülle veya mevcut diğer Python tabanlı paralel işlem paketlerinden birini denerim.

Genel olarak çok işlemciliğin ve paralelliğin püf noktası iyi bir bölümleme şeması bulmaktır:

  1. Girdileri daha küçük çalışma gruplarına ayırmanıza izin verir, ardından sonuçları mantıklı bir şekilde yeniden birleştirir.
  2. En az ek yükü ekler (bazıları seri işlemeye kıyasla kaçınılmazdır) ve
  3. Optimum performans için sistem kaynaklarını en iyi şekilde kullanmak için çalışma setinin boyutunu ayarlamanıza izin verir.

Bu cevapta oluşturduğum betiği başlangıç ​​noktası olarak kullanabilirsiniz: ArcGIS Desktop için Bina Gölgelerini ArcPy / Python'a Oluşturmak için Porting Avenue kodu?

Konuyla ilgili şu ESRI Geoprocessing blog gönderisine de bakın: Python Çoklu İşlem - Yaklaşımlar ve Düşünceler

Çalıştığım daha ince taneli geometri dizileri yerine, kullandığınız araçların "kara kutu" niteliğinden dolayı, durumunuzun daha zor olacağını düşünüyorum. Belki de NumPy dizileriyle çalışmak kullanışlı olabilir.

Ayrıca arcpy'nin ötesine bakmak istersen bazı ilginç okuma materyalleriyle karşılaştım:

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.