2

プログラムの速度に問題があります。巨大な配列の 4 つの近傍の平均を計算したいと考えています。これが私のコードの一部です。最後の行を変更する方法はありますか? または、別の配列を使用する必要がありますか?

for a in np.arange(100000):
    for x in np.arange(size):
        for y in np.arange(size):
            if unchangeableflag[x*size+y] == 0:
                vnew[x*size+y] = (v[(x+1)*size+y] + v[(x-1)*size+y] + v[x*size+y+1] + v[x*size+y-1]) / 4.0
4

3 に答える 3

4

ループはまったく必要ありません。と がエントリを持つ 1 次元配列であると仮定するとv、次のことができます。vnewunchangeableflagsize*size

v = v.reshape(size, size)
vnew = vnew.reshape(size, size)
unchangeableflag = unchangeableflag.reshape(size, size)
average = v[1:-1, 2:]
average += v[1:-1, :-2] 
average += v[2:, 1:-1]
average += v[-2:, 1:-1]
average /= 4.0
vnew[1:-1, 1:-1][unchangeableflag[1:-1, 1:-1] == 0] = average

しかし、あなたは実際に何を達成しようとしていますか?これは、離散ラプラシアンのいくつかのアプリケーションで回避できるように疑わしく見えます。

v(これはに浮動小数点数が含まれていることを前提としていることに注意してください。 dtype「v」の が sim 整数型の場合は、少し変更する必要があります。)

于 2011-01-28T15:31:28.653 に答える
3

SciPy の畳み込みフィルターまたはgeneric_filterの使用を検討する必要があります。これはまだ計算集約的ですが、ループよりもはるかに高速です。通常、このタイプの平均化を行う場合、中心要素も含まれます。これらのソリューションは、多次元配列にも適用されることに注意してください。

from scipy import ndimage
footprint = scipy.array([[0,0.25,0],[0.25,0,0.25],[0,0.25,0]])
filtered_array = scipy.convolve(array, footprint)

また

from scipy import ndimage
def myfunction(window):
    return (window[0,1] + window[1,0] + window[1,2] + window[2,1]) / 4
filtered_array = scipy.generic_filter(array, myfunction, size=3)
于 2011-01-28T15:44:35.340 に答える
1

よくわかりませんが、いくつかの不変条件を削除できます。

for a in np.arange(100000):
    for x in np.arange(size):
        for y in np.arange(size):
            t = x*size+y
            if unchangeableflag[t] == 0:
                vnew[t] = (v[t+size] + v[t-size] + v[t+1] + v[t-1]) / 4.0
于 2011-01-28T15:17:06.230 に答える