2016-07-20 5 views
1

가우스 웨이팅 메커니즘을 사용하여 각 포인트의 왼쪽과 오른쪽으로 3 * 너비 값을 평균화하여 곡선을 부드럽게하는 가중 이동 평균 기능이 있습니다. 나는 [시작, 끝]에 묶인 영역을 매끄럽게하는 것에 대해서만 걱정합니다. 다음 코드는 작동하지만 문제는 큰 배열의 런타임입니다.가중 이동 평균 필터 기능의 런타임 향상?

import numpy as np 
def weighted_moving_average(x, y, start, end, width = 3): 
    def gaussian(x, a, m, s): 
     return a*exp(-(x-m)**2/(2*s**2)) 
    cut = (x>=start-3*width)*(x<=end+3*width) 
    x, y = x[cut], y[cut] 
    x_avg = x[(x>=start)*(x<=end)] 
    y_avg = np.zeros(len(x_avg)) 
    bin_vals = np.arange(-3*width,3*width+1) 
    weights = gaussian(bin_vals, 1, 0, width) 
    for i in range(len(x_avg)): 
     y_vals = y[i:i+6*width+1] 
     y_avg[i] = np.average(y_vals, weights = weights) 
    return x_avg, y_avg 

제 생각에 NumPy 배열을 반복하는 것은 일반적으로 비효율적입니다. 누구든지 for 루프를 런타임에보다 효율적인 것으로 대체 할 생각이 있는지 궁금합니다.

감사

슬라이싱 및 가중 평균 창/합산하여 기본적 커널이 대칭으로되는 1 차원 컨볼 루션에 대응

답변

2

. 이제 1D convolution의 경우 NumPy는 np.convolve에 매우 효율적인 구현을 제공하며이를 사용하여 루프를 제거하고 y_avg을 제공 할 수 있습니다. 따라서, 우리는 그렇게 같은 벡터화 구현을 할 것이다 -

y_sums = np.convolve(y,weights[::-1],'valid') 
y_avg = np.true_divide(y_sums,weights.sum()) 
0

큰 배열을 통해 반복의 주된 관심사는 큰 배열에 대한 메모리 할당 비싼 될 수 있으며, 모든 일이 전에 초기화되어야한다는 것입니다 루프를 시작할 수 있습니다.

이 특별한 경우에 나는 Divakar가 말하는 것과 같이 갈 것입니다. 일반적으로

, 당신 정말 큰 컬렉션을 반복하는을 필요로하는 곳에 당신이 상황에서 자신을 찾을 경우, 반복자 대신 배열을 사용합니다. 이와 같이 비교적 간단한 경우 rangexrange (https://docs.python.org/2/library/functions.html#xrange 참조)으로 바꿉니다.