3

大規模なGISデータセット(10000 x 10000配列)をガウス平滑化しようとしています。私の現在のアプローチは、配列全体をメモリにロードし、平滑化してから書き戻すことです。次のようになります。

big_array = band_on_disk.ReadAsArray()
scipy.ndimage.gaussian_filter(big_array, sigma, output=smoothed_array)
output_band.WriteArray(smoothed_array)

大きなラスターMemoryErrorの場合は、その配列のサブブロックをロードしたいのですが、隣接するサブブロックに影響を与える領域のガウススムースを処理する方法がわかりません。

アレイ全体を正しく平滑化しながら、より小さなメモリフットプリントで動作するように、上記のアルゴリズムを修正する方法に関するアドバイスはありますか?

4

1 に答える 1

6

メモリマップトファイルを使用してみてください。

適度なメモリ使用量と耐えられるほど高速

アレイの1つをメモリに入れる余裕がある場合、これは耐えられるほど高速です。

import numpy as np
from scipy.ndimage import gaussian_filter

# create some fake data, save it to disk, and free up its memory
shape = (10000,10000)
orig = np.random.random_sample(shape)
orig.tofile('orig.dat')
print 'saved original'
del orig

# allocate memory for the smoothed data
smoothed = np.zeros((10000,10000))

# memory-map the original data, so it isn't read into memory all at once
orig = np.memmap('orig.dat', np.float64, 'r', shape=shape)
print 'memmapped'

sigma = 10 # I have no idea what a reasonable value is here
gaussian_filter(orig, sigma, output = smoothed)
# save the smoothed data to disk
smoothed.tofile('smoothed.dat')

メモリ使用量が少なく、非常に遅い

どちらかの配列を一度にメモリに入れる余裕がない場合は、元の配列と平滑化された配列の両方をメモリマッピングできます。これはメモリ使用量が非常に少ないですが、少なくとも私のマシンでは非常に遅いです。

このコードの最初の部分は、元の配列を一度にチートして作成し、それをディスクに保存するため、無視する必要があります。これをコードに置き換えて、ディスク上に段階的に構築したデータをロードできます。

import numpy as np
from scipy.ndimage import gaussian_filter

# create some fake data, save it to disk, and free up its memory
shape = (10000,10000)
orig = np.random.random_sample(shape)
orig.tofile('orig.dat')
print 'saved original'
del orig

# memory-map the original data, so it isn't read into memory all at once
orig = np.memmap('orig.dat', np.float64, 'r', shape=shape)
# create a memory mapped array for the smoothed data
smoothed = np.memmap('smoothed.dat', np.float64, 'w+', shape = shape)
print 'memmapped'

sigma = 10 # I have no idea what a reasonable value is here
gaussian_filter(orig, sigma, output = smoothed)
于 2012-10-11T18:29:24.967 に答える