Menggunakan arcgis desktop 10.3.1 Saya memiliki skrip yang menggunakan kursor pencarian untuk menambahkan nilai ke daftar dan kemudian menggunakan min () untuk menemukan integer terkecil. Variabel tersebut kemudian digunakan dalam skrip. Kelas Fitur memiliki 200.000 baris dan skrip membutuhkan waktu yang sangat lama untuk diselesaikan. Apakah ada cara untuk melakukan ini lebih cepat? Saat ini saya pikir saya hanya akan melakukannya dengan tangan daripada menulis naskah karena lamanya waktu yang dibutuhkan.
import arcpy
fc = arcpy.env.workspace = arcpy.GetParameterAsText(0)
Xfield = "XKoordInt"
cursor = arcpy.SearchCursor(fc)
ListVal = []
for row in cursor:
ListVal.append(row.getValue(Xfield))
value = min(ListVal)-20
print value
expression = "(!XKoordInt!-{0})/20".format(value)
arcpy.CalculateField_management (fc, "Matrix_Z" ,expression, "PYTHON")
arcpy.Statistics_analysis
? desktop.arcgis.com/en/arcmap/10.3/tools/analysis-toolbox/…min_val = min([i[0] for i in arcpy.da.SearchCursor(fc,Xfield)])
Jawaban:
Saya dapat melihat beberapa hal yang mungkin menyebabkan skrip Anda lambat. Hal yang mungkin sangat lambat adalah
arcpy.CalculateField_management()
fungsinya. Anda harus menggunakan kursor, dengan beberapa besaran lebih cepat. Juga, Anda mengatakan Anda menggunakan ArcGIS Desktop 10.3.1, tetapi Anda menggunakan kursor gaya lama ArcGIS 10.0, yang juga jauh lebih lambat.Operasi min () bahkan pada daftar 200K akan cukup cepat. Anda dapat memverifikasi ini dengan menjalankan cuplikan kecil ini; itu terjadi dalam sekejap mata:
Lihat apakah ini lebih cepat:
EDIT:
Saya menjalankan beberapa tes waktu dan seperti yang saya duga, kalkulator lapangan mengambil hampir dua kali lipat panjang kursor gaya baru. Menariknya, kursor gaya lama ~ 3x lebih lambat dari kalkulator lapangan. Saya membuat 200.000 poin acak dan menggunakan nama bidang yang sama.
Fungsi dekorator digunakan untuk menentukan waktu setiap fungsi (mungkin ada sedikit overhead dalam pengaturan dan meruntuhkan fungsi, jadi mungkin modul timeit akan sedikit lebih akurat untuk menguji snippet).
Inilah hasilnya:
Dan di sini adalah kode yang saya gunakan (memecah semuanya menjadi fungsi individu untuk menggunakan
timeit
dekorator):Dan akhirnya, inilah hasil cetak sebenarnya dari konsol saya.
Sunting 2: Baru saja memposting beberapa tes yang diperbarui, saya menemukan sedikit cacat pada
timeit
fungsi saya .sumber
"XKoordInt"
. Lihat hasil edit saya, yang harus Anda lakukan adalah melewati nol.range
. ArcGIS masih menggunakan Python 2.7, jadi ia mengembalikan alist
. Tetapi dalam 3.x,range
adalah jenis objeknya sendiri yang mungkin memiliki optimisasi. Tes yang lebih andal adalahmin(list(range(200000)))
, yang akan memastikan Anda bekerja dengan daftar sederhana. Juga pertimbangkan untuk menggunakantimeit
modul untuk pengujian kinerja.Seperti yang ditunjukkan oleh @crmackey, porsi lambat mungkin disebabkan oleh metode bidang hitung. Sebagai alternatif dari solusi lain yang sesuai, dan dengan asumsi Anda menggunakan geodatabase untuk menyimpan data Anda, Anda bisa menggunakan perintah Order By sql untuk mengurutkan dalam urutan naik sebelum melakukan kursor pembaruan.
Dalam hal ini klausa tempat menghapus nol sebelum melakukan kueri, atau Anda dapat menggunakan contoh lain yang memeriksa Tidak ada sebelum memperbarui.
sumber
min()
. Saya akan memasukkan ini dalam tes kecepatan saya juga untuk menunjukkan peningkatan kinerja.0.56
detik, yang tidak sebanyak keuntungan kinerja seperti yang saya harapkan.Anda juga dapat menggunakan numpy dalam kasus-kasus seperti ini, meskipun akan lebih intensif memori.
Anda masih akan mendapatkan leher botol saat memuat data ke array numpy dan kemudian kembali ke sumber data lagi, tetapi saya telah menemukan bahwa perbedaan kinerja lebih baik (mendukung numpy) dengan sumber data yang lebih besar, terutama jika Anda memerlukan banyak statistik / perhitungan .:
sumber
Mengapa tidak mengurutkan tabel naik, lalu gunakan kursor pencarian untuk mengambil nilai untuk baris pertama? http://pro.arcgis.com/en/pro-app/tool-reference/data-management/sort.htm
sumber
Saya akan membungkusnya
SearchCursor
dalam ekspresi generator (yaitumin()
) untuk kedua kecepatan dan ringkas. Kemudian gabungkan nilai minimum dari ekspresi generator dalam suatuda
tipeUpdateCursor
. Sesuatu seperti yang berikut ini:sumber
SearchCursor
seharusnya ditutup ketika Anda selesai dengan itu?Dalam loop Anda, Anda memiliki dua referensi fungsi yang direvaluasi untuk setiap iterasi.
for row in cursor: ListVal.append(row.getValue(Xfield))
Seharusnya lebih cepat (tapi sedikit lebih rumit) untuk memiliki referensi di luar loop:
sumber
append()
metode bawaan darilist
tipe data. Saya tidak berpikir ini adalah di mana kemacetannya terjadi, saya berani bertaruh uang menghitung fungsi bidang adalah pelakunya. Ini dapat diverifikasi dengan menghitung kalkulator lapangan vs. kursor gaya baru.