Pengambilan sampel raster yang efisien dari miliaran poligon (kotak pembatas)

8

Bagaimana raster dapat dihitung secara efisien (dengan Python), diberikan satu set yang terdiri dari milyaran kotak pembatas (dibaca berurutan dari sebuah file), dan mengingat bahwa nilai-nilai raster untuk setiap sel harus memberikan jumlah kotak pembatas yang tumpang tindih?

Untuk raster 4000 * 4000

Saya sudah menghitung waktu pembuatan numpy matrix:

$ python -m timeit 'import numpy' 'a = numpy.zeros(shape=(4000,4000))'
10 loops, best of 3: 51.7 msec per loop

Pembuatan matriks python standar:

$ python -m timeit 'a = 4000*[0]' 'for i in range(4000):' ' a[i]=4000*[0]'
10 loops, best of 3: 218 msec per loop

Jadi numpy lebih cepat, tetapi masih 50 msec per loop, dengan satu miliar iterasi, menghasilkan waktu berjalan yang sama dengan sekitar satu tahun (0,05 msec * 1000000000/60/60/24/365 = 1,5 tahun)

Jadi ini bukan pilihan untuk mengambil sampel setiap poligon. Apa pendekatan khas untuk masalah ini?

Pimin Konstantin Kefaloukos
sumber
Saya ingin menyelesaikannya di satu komputer, jadi tidak ada solusi peta / pengurangan :-)
Pimin Konstantin Kefaloukos
2
Saya tidak mengerti pentingnya mengatur waktu operasi pembuatan raster. Proses ini perlu membuat raster yang mendasarinya tepat sekali. Mendominasi waktu eksekusi akan menjadi masalah penambahan jumlah dalam interior kotak pembatas. Yang harus Anda lakukan adalah mengoptimalkan lingkaran dalam ini. Itu bisa dibuat dengan sangat cepat dalam bahasa yang dikompilasi seperti C atau Fortran.
Whuber
Membuat zero-raster adalah perkiraan kasar saya tentang berapa lama waktu yang dibutuhkan untuk menambah jumlah dalam kasus yang buruk. Ini adalah batas bawah pada berapa lama kasus terburuk, di mana poligon sebesar raster, bahasa yang dikompilasi atau tidak. Pertanyaan sebenarnya adalah, mengingat raster 4000x4000, seberapa cepat seluruh raster dapat ditingkatkan di C atau Fortran pada laptop tingkat menengah, back-of-the-envelope?
Pimin Konstantin Kefaloukos
2
BB menentukan rentang baris yang diindeks oleh i0..i1 dan rentang kolom j0..j1. Dalam penyimpanan baris demi baris, Anda dapat meningkatkan X (i, j0..j1) dengan sangat cepat (ini adalah penyimpanan yang berdekatan). Itu mungkin dapat dilakukan pada sekitar 3E9 peningkatan / detik dan bahkan vektor jika Anda suka untuk operasi yang jauh lebih cepat. Loop i dari i0 hingga i1: yang menangani satu BB. Untuk setiap BB Anda harus mengubah koordinat batas menjadi (i0, i1, j0, j1), tapi itu tidak banyak overhead: itu bisa dilakukan lebih cepat daripada Anda dapat membaca koordinat.
whuber
1
Ada blog yang menarik di situs ESRI ini yang berbicara tentang menggunakan pemrosesan python dan multicore, dapat membantu? blogs.esri.com/esri/arcgis/2011/08/29/multiprocessing
Hornbydd

Jawaban:

2

Anda timeittermasuk impor numpy, yang akan menambah beberapa overhead. Jadi mengapa Anda tidak menulis kode untuk subset dari kotak pembatas dan waktu loop itu, kemudian gandakan untuk memperkirakan total waktu berjalan?

Memecahkannya pada komputer tunggal adalah serialnya, dan dengan operasi yang relatif sederhana, Anda mungkin tidak mendapatkan optimasi signifikan dari algoritma yang sudah sederhana. Anda dapat mencoba membaginya dalam semacam operasi pengurangan peta manual (saya tahu Anda memiliki peringatan "tanpa pengurangan peta"), dan menjalankan instance sebanyak yang Anda punya core. Mosaicking / penggabungan dan raster (langkah pengurangan) adalah operasi yang sangat cepat. Ini mungkin tidak akan terlalu menyakitkan untuk dikodekan daripada solusi multi-threaded.

Atau (atau tambahan), Anda dapat menulis sebuah program untuk menggabungkan kotak batas tertentu seperti yang tumpang tindih atau bersarang - ini akan memerlukan indeks spasial. Jika Anda tidak memilikinya, Anda mungkin menemukan membuat satu menguntungkan, terutama jika Anda secara lokal memparalelkan algoritma utama.

Juga, jangan abaikan paralelisasi multi-komputer dari tangan. Jika perkiraan terbaik Anda adalah lebih dari satu tahun, maka Anda perlu menambahkan berapa banyak uang waktu Anda untuk menjalankan versi komputer tunggal, dan menimbangnya dengan mempekerjakan beberapa waktu komputasi awan. Seperti yang dikatakan @whuber, 1024 GPU akan memeriksa data dengan begitu cepat, itu akan dikenakan biaya apa-apa, bahkan jika Anda menghabiskan seminggu untuk mendapatkan CUDA. Jika bos Anda melarang Anda mencobanya di lebih dari satu komputer, lakukan analisis biaya dan berikan padanya beberapa angka sulit - ia kemudian akan menimbang nilai data terhadap nilai waktu Anda.

MerseyViking
sumber
1

Jika saya mengerti dengan benar, yang Anda inginkan seperti merender set miliaran kotak pembatas Anda ke gambar. Kecuali bahwa alih-alih "mengecat" setiap poligon di atas sel (piksel) Anda menghitung (atau mengakumulasikan) mereka.

Anda dapat menggunakan (relatif) kode sederhana (dalam OpenGL, Vulcan, Direct3D) untuk merender poligon dan mengakumulasikan jumlah dalam buffer stensil. Hati-hati agar poligon jatuh pada batas piksel dengan tepat, dan pilih tipe data untuk buffer stensil agar penghitungan tidak meluap. Saya harapkan itu berjalan dalam beberapa detik pada satu GPU ...

Pablo H
sumber