Ускорьте программу, которая вычисляет среднее число соседей в огромном массиве - PullRequest
2 голосов
/ 28 января 2011

У меня проблема со скоростью моей программы.Я хочу посчитать среднее число четырех соседей в огромном массиве.Вот часть моего кода.У вас есть идеи, как изменить последнюю строку?Или я должен использовать другой массив?

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 ]

4 голосов
/ 28 января 2011

Вам не понадобится петля вообще.Предполагая, что v, vnew и unchangeableflag являются массивами 1-го порядка с 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 содержит числа с плавающей запятой. Если dtype для `v´ является симметричным типом,вам нужно небольшое изменение.)

3 голосов
/ 28 января 2011

Вам следует рассмотреть возможность использования фильтра свертки 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)

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)
1 голос
/ 28 января 2011

Я не уверен, но вы можете удалить некоторый инвариант.

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
...