tr.geologyidea.com
Daha

Python GDAL ReadAsArray'i Optimize Etme

Python GDAL ReadAsArray'i Optimize Etme


We are searching data for your request:

Forums and discussions:
Manuals and reference books:
Data from registers:
Wait the end of the search in all databases.
Upon completion, a link will appear to access the found materials.


Numpy (özellikle yeniden sınıflandırma) kullanarak tarama verileriyle çalışmak için GDAL ReadAsArray yöntemini kullanıyorum. Rasterlerim büyük olduğundan, dizileri bloklar halinde işliyorum, her blokta yineleniyor ve GeoExamples örneğine benzer bir yöntemle işliyorum.

Şimdi, tüm taramayı işlemek için geçen süreyi optimize etmek için bu blokların boyutunu en iyi nasıl ayarlayacağıma bakıyorum. Sayısal dizi boyutlarıyla ilgili sınırlamaların ve bir rasterin "doğal" blok boyutunu kullanmak için GDAL GetBlockSize kullanımının farkında olarak, "doğal" boyutun katlarından oluşan birkaç farklı blok boyutu kullanarak testler yapıyorum, aşağıdaki örnek kod ile:

import timeit try: import gdal hariç: from osgeo import gdal # Seçilen blok boyutu için taramayı diziler olarak okuma işlevi. def read_raster(x_block_size, y_block_size): raster = "büyük taramaya giden yol" ds = gdal.Open(raster) band = ds.GetRasterBand(1) xsize = band.XSize ysize = band.YSize blokları = y için xrange( 0, ysize, y_block_size): if y + y_block_size < ysize: rows = y_block_size else: rows = ysize - x için y xrange(0, xsize, x_block_size): if x + x_block_size < xsize: cols = x_block_size else: cols = xsize - x dizi = band.ReadAsArray(x, y, sütunlar, satırlar) del dizi blokları += 1 bant = Yok ds = Yok yazdır "{0} blok boyutu {1} x {2}:".format(bloklar, x_block_size, y_block_size) # Testi çalıştırma ve tamamlanması için geçen süreyi yazdırma işlevi. def timer(x_block_size, y_block_size): t = timeit.Timer("read_raster({0}, {1})".format(x_block_size, y_block_size), setup="__main__ import read_raster'dan") yazdır "	{:. 2f}s
".format(t.timeit(1)) raster = "büyük taramaya giden yol" ds = gdal.Open(raster) band = ds.GetRasterBand(1) # "doğal" blok boyutunu ve toplamını alın raster XY boyutu. block_sizes = band.GetBlockSize() x_block_size = block_sizes[0] y_block_size = blok_sizes[1] xsize = band.XSize ysize = band.YSize band = Yok ds = Yok # Farklı blok boyutlarıyla testler. timer(x_block_size, y_block_size) timer(x_block_size*10, y_block_size*10) timer(x_block_size*100, y_block_size*100) timer(x_block_size*10, y_block_size) timer(x_block_size*100, y_block_size)_size_size,*y_10_block_size_ timer(x_block_size, y_block_size*100) timer(xsize, y_block_size) timer(x_block_size, ysize) timer(xsize, 1) timer(1, ysize)

Aşağıdaki türde bir çıktı üretir:

474452 blok boyutu 256 x 16: 9.12s 4930 blok boyutu 2560 x 160: 5.32s 58 blok boyutu 25600 x 1600: 5.72s 49181 blok boyutu 2560 x 16: 4.22s 5786 blok boyutu 25600 x 16: 5.67s 47560 blok boyutu 256 x 160: 4.21s 4756 blok boyutu 256 x 1600: 5.62s 2893 blok boyutu 41740 x 16: 5.85s 164 blok boyutu 256 x 46280: 5.97s 46280 blok boyutu 41740 x 1: 5.00s 41740 blok boyutu 1 x 46280: 800.24s

Bunu, farklı boyut ve piksel türleriyle birkaç farklı raster için çalıştırmayı denedim ve x veya y boyutunda (bazı durumlarda her ikisi de) on kat artışın işlem süresini yarıya indirdiği benzer eğilimler alıyor gibi görünüyorum. yukarıdaki örnekte o kadar önemli olmasa da, en büyük rasterlerim için birkaç dakika anlamına gelebilir.

Öyleyse sorum şu, bu davranış neden oluyor?

İşlem süresini iyileştirmek için daha az blok kullanmayı bekliyordum, ancak en azını kullanan testler en hızlısı değil. Ayrıca, son test neden öncekinden çok daha uzun sürüyor? Satır veya sütuna göre veya okunmakta olan bloğun biçiminde toplam boyuta göre okuma için rasterlerle ilgili bir tür tercih var mı? Bundan almayı umduğum şey, girdinin boyutuna bağlı olarak bir rasterin blok boyutunu optimal bir değere ayarlayabilen temel bir algoritmayı bir araya getirme bilgisidir.

Girişimin, 256 x 16 "doğal" blok boyutuna sahip bir ESRI ArcINFO ızgara raster olduğunu ve bu örnekte rasterimin toplam boyutunun 41740 x 46280 olduğunu unutmayın.


Eşit bir blok boyutu kullanmayı denediniz mi? 200k x 200k piksel düzeninde ve oldukça seyrek olan raster verileriyle ilgileniyorum. Çok sayıda kıyaslama, süreçlerimiz için en verimli olan 256x256 piksel blokları sağladı. Bu, bir bloğu almak için kaç tane disk araması gerektiği ile ilgilidir. Blok çok büyükse, diske bitişik olarak yazmak daha zordur, bu da daha fazla arama anlamına gelir. Aynı şekilde, çok küçükse, tüm taramayı işlemek için çok sayıda okuma yapmanız gerekecektir. Ayrıca toplam boyutun ikinin gücü olmasını sağlamaya yardımcı olur. 256x256 tesadüfen gdal'deki varsayılan geotiff blok boyutudur, bu yüzden belki de aynı sonucu çıkardılar


Benim şüphem, GDAL'ın blok önbelleğine gerçekten çarpıyorsunuz ve bu, işlem hızı eğriniz üzerinde önemli bir etkisi olacak bir düğme.

Özellikle SettingConfigOptions'a bakınGDAL_CACHEMAX, bununla ilgili daha fazla ayrıntı için ve bu değeri önemli ölçüde daha büyük bir değere değiştirmenin simülasyonunuzla nasıl etkileşime girdiğini araştırın.


Videoyu izle: Read and write raster files with GDAL in Python