ArcGIS Araçları Olarak Çalışan Python Komut Dosyalarını Hızlandırma Yolları [kapalı]


31

Bu oldukça genel bir soru. Sadece GIS programcılarının araç kutusuna içe aktarıp çalıştırdığınız arkalı komut dosyalarını hızlandırmak için hangi ipuçlarını ve püf noktalarını kullandıklarını merak ediyorum.

Her gün çoğu ofisimde GIS verisi olmayan GIS verilerini kullanmalarına yardımcı olacak küçük senaryolar yazıyorum. ArcGIS 10.0 işleminin genel olarak 9.3.1'den daha yavaş olduğunu ve bazen bir python betiği çalıştırırken bazen daha yavaşladığını buldum.

Çalıştırılması 24 saatten fazla süren belirli bir senaryo örneğini listeleyeceğim. Bir rasterin alanını tampondaki her bir şekil için bir tampon içinde tablolayan bir döngüdür. Tampon yaklaşık 7000 şekle sahiptir. Bu kadar uzun sürmesi gerektiğine inanmıyorum. bir

while x <= layerRecords:

    arcpy.SetProgressorLabel("Tabulating Row: " + str(x) + " of " + str(ELClayerRecords))
    arcpy.SelectLayerByAttribute_management(Buff,"NEW_SELECTION", "Recno = " + str(x))                                  # Selecting the record
    TabulateArea(Buff, "Recno", MatGRID, "VALUE", ScratchWS + "/tab" + str(z) +".dbf", nMatGRIDc)                          # Tabulate the area of the single row

    arcpy.AddMessage ("          - Row: " + str(x) + " completed")
    x = x + 1
    z = z + 1

Herhangi biri söylemeden önce, tüm tamponda tablo alanını çalıştırdım, ancak 1 kayıttan daha fazla çalışırsa hatalar üretiyor. Bu kusurlu bir araç, ama onu kullanmak zorundayım.

Her neyse, herhangi birinin bu betiği nasıl optimize edeceğiniz veya hızlandıracağı konusunda bir fikri varsa, bu en çok takdir edilecektir. Aksi takdirde, ArcGIS'te kullanıldığında python için hileleriniz oldu mu?

Yanıtlar:


26

İşleminizi hızlandırmanıza yardımcı olacak birkaç potansiyel öneri:

  1. Layer By Attribute, ArcGIS Desktop’ı başlatmadan yalnızca Python komut dosyasında olabilir. "Buff" referansınızı, dosya tabanlı bir referanstan, ArcGIS'in seçim sorgularını karşı işleyebileceği bir "ArcGIS katmanı" referansına dönüştürmeniz gerekir. "While" döngüsünün üzerinde arcpy.MakeFeatureLayer_management ("buff", "buff_lyr") kullanın ve ardından "buff_lyr" kullanmak için while döngüsü altındaki referanslarınızı değiştirin.

  2. GP işlemlerinizi mümkün olduğunca in_memory çalışma alanını kullanarak işleyin ... Kaynağınızı belleğe taşımak için arcpy.CopyFeatures_management (shapefile, "in_memory \ memFeatureClass") kullanın. Bu, yalnızca belleğe ihtiyaç duyduğunuz tüm özellik sınıflarını okumak için yeterli RAM'iniz varsa işe yarar. Bununla birlikte, in_memory çalışma alanını kullanarak çalıştırılamayan bazı GP işlemleri olduğuna dikkat edin (Örn: Proje aracı).

ArcGIS 9.3 çevrimiçi yardım makalesinde " Orta seviye veri ve çizik çalışma alanı " (bu dilin 10.0 ve 10.1 yardımından kaldırıldığını unutmayın):

NOT: in_memory çalışma alanına yalnızca tablolar ve özellik sınıfları (noktalar, çizgiler, çokgenler) yazılabilir. İn_memory çalışma alanı alt türler, etki alanları, temsiller, topolojiler, geometrik ağlar ve ağ veri kümeleri gibi genişletilmiş coğrafi veritabanı öğelerini desteklemez. Sadece basit özellikler ve tablolar yazılabilir.

" Bellek içi çalışma alanını kullanma " ArcGIS 10.1 çevrimiçi yardım makalesinden :

Bellek içi çalışma alanına çıktı yazmaya karar verirken aşağıdaki hususlara dikkat edilmelidir:

  • Bellek içi çalışma alanına yazılan veriler geçicidir ve uygulama kapatıldığında silinir.
  • Tablolar, özellik sınıfları ve rasterler bellek içi çalışma alanına yazılabilir.
  • Bellek içi çalışma alanı, alt türler, etki alanları, temsiller, topolojiler, geometrik ağlar ve ağ veri kümeleri gibi genişletilmiş coğrafi veritabanı öğelerini desteklemez.
  • Özellik veri kümeleri veya klasörleri bellek içi çalışma alanında oluşturulamaz.

1
Bu harika! ArcMap dışında seçimleri kullanmanın bir yolunu aradım ama şu ana kadar başarısız oldum. Bu sorunla ilgili olarak, sıradaki zamanımı 20 saniyeden 13 saniyeye indirdi. Ancak, hızlı bir şekilde başka bir çalışma yaptım ve döngü içinde MakeFeatureLayer'ı kullandım ve 9 saniyeye düştü. Bunu, özellik katmanından tablolama yerine her şekilden bir özellik yaparak yaptım. Hala mümkünse daha da aşağı çekmek istiyorum, ama zaten çok daha hızlı bir süreç!
Cody Brown

# 2'de belirtildiği gibi, kaynak verilerinizin bir kopyasını in_memory'de yapmak için CopyFeatures'ı kullanın, sonra özellik_layıcınızı in_memory kaynağına karşı oluşturun. Belleğe ilk kopya önden birkaç saniye daha eklenebilir olsa da, copyfeatures + tabulate_areas işlemlerinin o anki modelinizden daha hızlı bir toplam işlem süresine sahip olduğunu görebilirsiniz.
RyanDalton

Bunu da denedim ve bu çözüm döngü işlemini daha hızlı hale getirecek gibi görünüyor, ancak yapmıyor. Döngüde özellik katmanının oluşturulması, döngü başına yaklaşık 8-10 saniye, döngüden önce özellik katmanının oluşturulması, döngü başına 11 - 14 saniye arasında sonuçlanır. Çözümünüz neden böyle ses çıkardığından daha hızlı işleyeceğinden emin değilim. 8GB RAM'im var, bu yüzden sorun olacağından şüpheliyim.
Cody Brown,

Ayrıca, döngüden önce özellikleri in_memory ile baş etmek ve ardından hala döngüde özellik katmanını oluşturmak biraz daha hızlı bir performansla sonuçlanır. Hemen hemen her döngü için satır başına 8 saniye kalır. Toplam işlem süresi 26 saatten 22'ye düşecek.
Cody Brown

Fikirlerinizi ekledikten sonra betiğim önemli ölçüde gelişti. Kendinize ve herkesin yardımına bir ton teşekkürler!
Cody Brown,

28

Genel python optimizasyon teknikleri size önemli miktarda zaman kazandırabilir.

Komut dosyalarınızdaki hold'lerin nerede olduğuna dair bir bilgi edinmek için gerçekten iyi bir teknik, yerleşik cProfile modülünü kullanmaktır:

from cProfile import run
run("code") # replace code with your code or function

Küçük bir veri örneği kullanarak test etmek, hangi fonksiyon çağrılarının en fazla zaman aldığını belirlemenizi sağlar.

Daha hızlı python kodu için genel işaretçiler:

  • Liste anlama, genellikle döngüden daha hızlıdır
  • Jeneratörler, listenin tamamını aynı anda üretmek yerine, aynı anda bir ürün üretir
  • Python 2'de aralık yerine xrange kullanın (3'te gerekli değildir)
  • Kümeler, kümede bir öğenin bulunup bulunmadığını belirlemeye gelince, preform listelerini çıkartabilir, ancak içerikleri üzerinde yineleme söz konusu olduğunda genellikle listelerden daha yavaştır Kaynak
  • İşlev çağrıları performans açısından maliyetli olabilir Kaynak
  • Diğer ipuçları ve detaylar burada kontrol edin Python Perfomance İpuçları ve burada 10 Python Optimizasyon İpuçları ve Sorunları

Komut dosyanızla ilgili olarak, ArcPy ile ilgili yorum yapamam çünkü bu bilgisayarda Arc yüklü değil, ancak bir döngü olup olmadığını görmek için bir süre döngüsü yerine for döngüsü kullanmayı deneyebilirsiniz. Ayrıca x = x + 1, x + = 1 olarak yazılabilir:

for record in layerRecords:
arcpy.SetProgressorLabel("Tabulating Row: " + str(x) + " of " + str(ELClayerRecords))
arcpy.SelectLayerByAttribute_management(Buff,"NEW_SELECTION", "Recno = " + str(x))                                  # Selecting the record
TabulateArea(Buff, "Recno", MatGRID, "VALUE", ScratchWS + "/tab" + str(z) +".dbf", nMatGRIDc)                          # Tabulate the area of the single row

arcpy.AddMessage ("          - Row: " + str(x) + " completed")
x+=1
y+=1

1
Son merminize bıraktığınız iki bağlantıyı kullandım ve komut dosyama birkaç hızlı düzeltme ile gerçekten yardım edebildim!
Cody Brown

İki doğru cevabı verebilseydim yapardım. Cevabınız gerçekten python'u nasıl hızlandıracağınızla ilgili birçok fikir sunsa da, @RyanDalton en fazla etkiye sahip olan fikri sundu. Bir ton teşekkürler!
Cody Brown,

13

Bilgisayardaki dahili sürücüye yazdığınızdan emin olun. Gerekmediğinde ağ üzerinden ulaşmak işlemi gerçekten yavaşlatabilir. Müteakip okuma-yazma işlemlerini mümkün olduğu kadar çabuk tutmak için, verilerin işlemdeki ilk adım olarak kopyalanması daha da hızlı olabilir.

Komut dosyasını tamamen ArcMap'in dışında çalıştırmak çok daha hızlı olabilir. İşlem sırasında bir Harita gerekli değilse, ArcMap'i kullanmayın.


ArcCatalog'dan bir modelin içinde bir komut dosyası çalıştırmanın (kendiliğinden bir Calculate Valueiletişim kutusu içinde ) aynı komut dosyasını ArcMap'taki ArcPy penceresinden çalıştırmaktan daha hızlı işleyeceğini gördüm. Bu tamamen bir anekdot gözlem olsa da.
Cindy Jayakumar

1
Tabula'nın düzgün çalışması için bir haritaya ihtiyacım olduğuna inanıyorum, ancak bunu deneyeceğim. ArcMap dışında çalışırsa, hızlanacağına bahse girerim. Ayrıca zaten yerel diski çalıştırıyorum, bu betiğin hızını ikiye katladı bile.
Cody Brown

Ne yazık ki, Seçim, ArcMap dışında çalışmaz ve zorunludur çünkü tablo şeklini şekil olarak yapmam gerekiyor.
Cody Brown

3
@ CodyBrown- Bir ArcMap oturumu dışında çalışmama seçiminde yanılıyorsunuz. MakeFeatureLayer aracını kullanma konusundaki cevabımı görün.
RyanDalton

Ryan haklı. Seçim aracı kendi başına kullanıldığında, konumsal verilerinizin veya tablo verilerinizin tablo görünümünü oluşturur. ModelBuilde'de veya bir komut dosyasında kullanırken, bir görünüm oluşturmanız ve sizin durumunda, MakeFeatureLayer aracını kullanarak oluşturmanız gerekir.
dchaboya

6

Bu, ArcPap araçlarını ArcMap içinde çalıştırmak için sorunuzu yanıtlamayabilir, ancak coğrafi işleme araçları ve Python ile bazı etli işlemler yapmam gerektiğinde, IDE PyScripter kullanarak GIS sisteminin dışında çalıştırma eğilimindeyim . Daha hızlı çalıştığını buldum. Ayrıca küçük geçici çıktı veri setleri için bir RAMDISK kullandım (biraz da in_memory çalışma alanı gibi )

Onlar benim en iyi ipuçlarım! :)


2
Bu cevabı biraz bulanıklaştırmak için, Python IDE'lerden komut dosyaları çalıştırırken birçok kişi değişkenleri ve diğer çeşitli hata ayıklama yardımlarını izlemeye yardımcı olmak için geri izleme işlevini enjekte eder. Bu işlev, ALL TIME olarak adlandırılan çok fazla şey yaparsa komut dosyalarını büyük ölçüde yavaşlatabilir ve bazen bu kullanıcı müdahalesi olmadan örtük olarak yüklenir. ArcMap'ta çalışan bir Python senaryosunun 4 dakika içinde koştuğunu gözlemlediğim özel bir patolojik vaka vardı, aynı zamanda Wing IDE'den gelen aynı senaryo 3 saat sürdü. Kanatsız Python.exe'den çalıştırıldığında, ~ 2-3 dakikalık çalışma zamanı alanına geri döndü.
Jason Scheirer

1
Senaryolarımı ArMap'ta ayarlamak için başım ağrıyordu, bazen Pyscripter'a dönene kadar tamamen yapamam, herhangi bir optimizasyon ipucu kullanmadan yürütme süresini Arcmap'a göre kesebilir.
geogeek

@ JasonScheirer bunu kapatmak için Wing'deki ince ayarını buldunuz mu? Bir tane olduğundan eminim.
Curtis Fiyatı

5

Arcpy.SetProgressorLabel hakkında yorum yapmayı deneyin ve ne kadar hızlandırdığınızı görün. DOS sine geri dönen herhangi bir ekran çıktısının işlem sürelerini önemli ölçüde yavaşlattığını gördüm. Bu çıktıyı gerçekten görmeniz gerekiyorsa, her Nth loop'u göstermeye çalışın.


4

import xxxxKullanılmayan tüm çizgileri kaldırdığınızdan emin olun .

(yani import Math, henüz sahip olduğunuz herhangi bir matematiksel işlevi kullanmıyorsanız , komut dosyasının yüklenmesinden biraz zaman alacaktır)

Bu, çalışan tek bir komut dosyası üzerinde büyük bir etkiye sahip olmayacak olsa da (sizinki gibi), sık sık ve tekrarlayan olarak çalışan tüm komut dosyalarını etkileyecektir.


7
Herhangi bir standart Python modülünün, arcpy modülünün başlatılması için harcadığı sürenin binde birinden fazlasını aldığından şüpheliyim.
blah238

1
@ blah238 import Mathmuhtemelen kötü bir örnekti. Bununla birlikte, daha büyük ArcPy kütüphanelerinin bazıları, yüklenmesi çok zaman alır.
nagytech

1
bu hala saatlerce değil, sadece saniye (en fazla!) tıraş oluyor
Mike T

1
@MikeToews Sık sık ve tekrarlayan kodlar için birkaç saniye, birkaç gün / hafta boyunca birkaç saniye ekler. Bu, OP'nin ana sorununu çözmese de, genel ipuçları istedi.
nagytech
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.