Cara untuk Mempercepat Skrip Python Berjalan Sebagai Alat ArcGIS [ditutup]

31

Ini pertanyaan yang cukup umum. Saya hanya ingin tahu tips dan trik apa yang telah digunakan programmer GIS untuk mempercepat skrip arcpy yang Anda impor ke dalam kotak peralatan dan jalankan.

Saya bekerja paling banyak setiap hari menulis skrip kecil untuk membantu pengguna non-GIS di kantor saya memproses data GIS. Saya telah menemukan bahwa pemrosesan ArcGIS 10.0 secara umum lebih lambat dari 9.3.1 dan kadang-kadang bahkan lebih lambat ketika menjalankan skrip python.

Saya akan mencantumkan contoh skrip tertentu yang berjalan lebih dari 24 jam. Itu adalah loop yang menabulasi area raster di buffer untuk setiap bentuk di buffer. Buffer memiliki sekitar 7000 bentuk. Saya tidak percaya itu harus berjalan selama ini. SEBUAH

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

Sebelum ada yang mengatakannya, saya telah menjalankan area tabulasi pada seluruh buffer, tetapi menghasilkan kesalahan jika dijalankan pada lebih dari 1 record. Ini alat yang cacat, tapi saya harus menggunakannya.

Bagaimanapun, jika ada yang punya ide tentang bagaimana mengoptimalkan, atau mempercepat skrip ini, itu akan sangat dihargai. Jika tidak, apakah Anda punya trik mempercepat untuk python, ketika digunakan di ArcGIS?

Cody Brown
sumber

Jawaban:

26

Beberapa saran potensial untuk membantu mempercepat proses Anda adalah:

  1. Select Layer By Attribute dapat dibuat dalam skrip Python saja, tanpa pernah meluncurkan ArcGIS Desktop. Anda perlu mengonversi referensi "buff" Anda dari referensi berbasis file ke referensi "ArcGIS layer", yang ArcGIS dapat memproses kueri pemilihan terhadap. Gunakan arcpy.MakeFeatureLayer_management ("buff", "buff_lyr") di atas loop "while" Anda, dan kemudian ubah referensi Anda di bawah loop while untuk menggunakan "buff_lyr".

  2. Memproses sebanyak mungkin operasi GP Anda menggunakan ruang kerja in_memory sebanyak mungkin ... Gunakan arcpy.CopyFeatures_management (shapefile, "in_memory \ memFeatureClass") untuk memindahkan sumber Anda ke dalam memori. Ini hanya berfungsi dengan baik jika Anda memiliki RAM yang cukup untuk membaca semua kelas fitur yang Anda butuhkan ke dalam memori. Berhati-hatilah, bagaimanapun, bahwa ada beberapa operasi GP yang tidak dapat berjalan menggunakan in_memory workspace (Eg: the Project tool).

Dari artikel bantuan online ArcGIS 9.3 " Data antara dan ruang kerja awal " (catatan, bahasa ini telah dihapus dari bantuan 10.0 & 10.1):

CATATAN: Hanya tabel dan kelas fitur (titik, garis, poligon) yang dapat ditulis ke ruang kerja in_memory. Ruang kerja in_memory tidak mendukung elemen geodatabase yang diperluas seperti subtipe, domain, representasi, topologi, jaringan geometris, dan dataset jaringan. Hanya fitur dan tabel sederhana yang dapat ditulis.

Dari ArcGIS 10.1 artikel bantuan online " Menggunakan ruang kerja di-memori ":

Pertimbangan berikut harus dibuat dalam memutuskan untuk menulis output ke ruang kerja di-memori:

  • Data yang ditulis ke ruang kerja di memori bersifat sementara dan akan dihapus ketika aplikasi ditutup.
  • Tabel, kelas fitur, dan raster dapat ditulis ke ruang kerja di-memori.
  • Ruang kerja di-memori tidak mendukung elemen geodatabase yang diperluas seperti subtipe, domain, representasi, topologi, jaringan geometris, dan kumpulan data jaringan.
  • Dataset atau folder fitur tidak dapat dibuat di ruang kerja di memori.
Ryan Dalton
sumber
1
Itu luar biasa! Saya telah mencari cara untuk menggunakan pilihan di luar ArcMap tetapi, sejauh ini tidak berhasil. Dalam hal masalah ini, sebenarnya mendorong waktu saya per baris ke sekitar 13 detik dari 20 detik. Tapi, saya melakukan pekerjaan cepat lainnya dan melakukan MakeFeatureLayer dalam loop dan turun menjadi 9 detik. Saya melakukan ini dengan membuat fitur dari setiap bentuk daripada tabulasi dari lapisan fitur. Saya masih ingin membahasnya lebih jauh jika memungkinkan, tetapi ini merupakan proses yang jauh lebih cepat!
Cody Brown
Seperti disebutkan di # 2, gunakan CopyFeatures untuk membuat salinan data sumber Anda di_memory, lalu buat fitur_layer Anda melawan sumber in_memory. Meskipun salinan awal ke memori dapat menambahkan beberapa detik di muka, Anda mungkin menemukan bahwa pemrosesan fitur copy + tabulate_areas memiliki total waktu pemrosesan yang lebih cepat daripada model Anda saat ini.
RyanDalton
Saya mencobanya juga dan sepertinya solusi itu akan membuat proses loop lebih cepat tetapi, tidak. Membuat layer fitur dalam loop menghasilkan sekitar 8-10 detik per loop, sementara membuat layer fitur sebelum loop menghasilkan 11 - 14 detik per loop. Saya tidak terlalu yakin mengapa karena solusi Anda sepertinya akan diproses lebih cepat. Saya memiliki 8GB RAM, jadi saya ragu itu akan menjadi masalah.
Cody Brown
Juga mengatasi fitur ke in_memory sebelum loop dan kemudian masih membuat lapisan fitur dalam loop menghasilkan kinerja yang sedikit lebih cepat. Cukup banyak tetap 8 detik per baris untuk setiap loop. Yang akan mengurangi total waktu proses dari 26 jam menjadi 22.
Cody Brown
Setelah menambahkan ide Anda, skrip saya meningkat secara dramatis. Terima kasih banyak atas bantuan Anda dan semua orang!
Cody Brown
28

Teknik optimasi python umum dapat menghemat banyak waktu.

Salah satu teknik yang sangat bagus untuk mendapatkan lowdown di mana penahanan dalam skrip Anda adalah menggunakan modul cProfile bawaan:

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

Pengujian menggunakan sampel data kecil akan memungkinkan Anda menentukan dengan tepat panggilan fungsi mana yang paling banyak menghabiskan waktu.

Petunjuk umum untuk kode python yang lebih cepat:

  • Pemahaman daftar umumnya lebih cepat daripada pengulangan
  • Generator menghasilkan satu item sekaligus dan bukannya menghasilkan seluruh daftar sekaligus
  • Gunakan xrange alih-alih rentang dalam python 2 (tidak perlu dalam 3)
  • Set bisa mengeluarkan daftar sebelumnya ketika datang untuk menentukan apakah suatu item hadir dalam set tetapi umumnya lebih lambat dari daftar ketika datang untuk beralih pada isinya Sumber
  • Panggilan fungsi dapat mahal untuk Sumber kinerja
  • Lebih banyak tips dan detail periksa di sini Tips Kinerja Python dan di sini 10 Tips dan Masalah Optimasi Python

Sehubungan dengan skrip Anda, saya tidak dapat mengomentari aspek ArcPy karena saya tidak memiliki Arc yang diinstal pada komputer ini, tetapi Anda mungkin ingin mencoba menggunakan for loop alih-alih loop sementara melihat apakah itu meningkatkan sesuatu. Juga x = x + 1 dapat ditulis sebagai x + = 1:

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
James Milner
sumber
1
Saya menggunakan dua tautan yang Anda tinggalkan di bullet terakhir Anda dan dapat benar-benar membantu skrip saya dengan beberapa perbaikan cepat!
Cody Brown
Jika saya dapat memberikan dua jawaban yang benar saya akan melakukannya. Sementara jawaban Anda benar-benar menawarkan banyak ide tentang cara mempercepat python, @RyanDalton menawarkan ide yang memiliki dampak paling besar. Terima kasih banyak!
Cody Brown
13

Pastikan Anda menulis ke drive internal di komputer. Menjangkau seluruh jaringan ketika tidak perlu dapat benar-benar memperlambat pemrosesan. Bahkan bisa lebih cepat untuk menyalin data sebagai langkah pertama dalam proses untuk menjaga baca-tulis berikutnya secepat mungkin

Menjalankan skrip sepenuhnya di luar ArcMap bisa jauh lebih cepat. Jika Peta tidak diperlukan selama pemrosesan, maka jangan gunakan ArcMap.

mhoran_psprep
sumber
Saya telah menemukan bahwa menjalankan skrip di dalam model dari ArcCatalog (dengan sendirinya di dalam Calculate Valuedialog) akan memproses lebih cepat daripada menjalankan skrip yang sama dari jendela ArcPy di ​​ArcMap. Itu murni pengamatan anekdotal.
Cindy Jayakumar
1
Saya yakin saya perlu peta agar Tabulate berfungsi dengan baik, tetapi saya akan mencoba ini. Jika itu bekerja di luar ArcMap, saya yakin itu akan mempercepat. Juga saya sudah menjalankan disk lokal, yang sudah dua kali lipat kecepatan skrip.
Cody Brown
Sayangnya Select tidak berfungsi di luar ArcMap dan itu perlu karena saya perlu melakukan tabulasi bentuk demi bentuk.
Cody Brown
3
@ CodyBrown- Anda salah tentang Pilih yang tidak berfungsi di luar sesi ArcMap. Lihat respons saya tentang menggunakan alat MakeFeatureLayer.
RyanDalton
Ryan benar. Ketika alat pilih digunakan sendiri, itu menciptakan tampilan tabel baik data spasial atau data tabel Anda. Saat menggunakannya dalam ModelBuilde atau dalam skrip, Anda harus membuat tampilan, dan dalam kasus Anda, membuatnya dengan menggunakan alat MakeFeatureLayer.
dchaboya
6

Ini mungkin tidak menjawab pertanyaan Anda untuk menjalankan alat ArcPy di ​​dalam ArcMap tetapi ketika saya perlu melakukan pengolahan gemuk dengan alat geo-processing dan Python saya cenderung menjalankannya di luar sistem GIS menggunakan IDE PyScripter . Saya menemukan ini berjalan lebih cepat. Saya juga menggunakan RAMDISK untuk dataset output sementara kecil (sedikit seperti ruang kerja in_memory )

Yah mereka adalah tips utama saya! :)

Hornbydd
sumber
2
Untuk memperkeruh jawaban ini agak, ketika menjalankan skrip dari Python IDEs banyak menyuntikkan fungsi traceback untuk membantu dalam menonton variabel dan berbagai bantuan debugging lainnya. Fungsi ini secara besar-besaran dapat memperlambat skrip jika ia melakukan terlalu banyak karena dipanggil SEMUA WAKTU, dan kadang-kadang ini dipasang secara implisit tanpa campur tangan pengguna. Ada kasus patologis tertentu yang saya amati di mana skrip Python berjalan di ArcMap berjalan dalam 4 menit, sedangkan skrip yang sama dari Wing IDE memakan waktu 3 jam. Segera setelah dijalankan dari Python.exe tanpa Wing, ia kembali ke wilayah runtime ~ 2-3 menit.
Jason Scheirer
1
Saya mengalami sakit kepala untuk menyetel skrip saya di ArMap, kadang-kadang saya tidak bisa sepenuhnya, sampai saya beralih ke Pyscripter, itu dapat memangkas waktu eksekusi dibandingkan dengan Arcmap, tanpa menggunakan tip optimasi.
geogeek
@JasonScheirer apakah Anda menemukan tweak di Wing untuk mematikan ini? Saya yakin ada satu.
Harga Curtis
5

Coba komentari arcpy.SetProgressorLabel dan lihat seberapa cepat Anda mempercepatnya. Saya telah menemukan bahwa setiap output layar, kembali ke DOS linglung, secara drastis memperlambat waktu pemrosesan. Jika Anda benar-benar perlu melihat output itu, coba perlihatkan setiap loop ke-N.

pengguna30749
sumber
4

Pastikan Anda menghapus import xxxxbaris yang tidak digunakan.

(mis. jika Anda belum menggunakan fungsi matematika apa pun yang Anda miliki import Math, ini akan memakan waktu dari pemuatan skrip)

Meskipun ini tidak akan berdampak besar pada skrip tunggal yang berjalan (seperti skrip Anda), ini akan memengaruhi skrip apa pun yang sering berjalan dan berulang.

nagytech
sumber
7
Saya ragu modul standar Python membutuhkan lebih dari seperseribu waktu yang dibutuhkan modul arcpy untuk menginisialisasi.
blah238
1
@ blah238 import Mathmungkin contoh yang buruk. Namun, beberapa perpustakaan ArcPy yang lebih besar membutuhkan banyak waktu untuk memuat.
nagytech
1
ini masih memangkas hanya beberapa detik (paling banyak!), bukan jam
Mike T
1
@MikeToews Untuk skrip yang sering dan berulang, beberapa detik bertambah selama beberapa hari / minggu, dll. Walaupun dosen ini tidak menyelesaikan masalah utama OP, dia memang meminta tips umum.
nagytech