加速程序计算大阵列中邻居的平均值

时间:2011-01-28 15:12:23

标签: python numpy performance numerical

我的程序速度有问题。我想计算一个巨大阵列中四个邻居的平均值。这是我的代码的一部分。你有什么想法如何改变最后一行?或者我应该使用另一个阵列?

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

3 个答案:

答案 0 :(得分:4)

根本不需要循环。假设vvnewunchangeableflag是带有size*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包含浮点数。如果`v'的dtype是sime整数类型,则需要稍作修改。)

答案 1 :(得分:3)

您应该考虑使用SciPy的convolution filtergeneric_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)

OR

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)

答案 2 :(得分: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