2017-04-15 4 views
1

나는 자체 시스템 모니터링 도구를 만드는 중입니다. 내가 장치 (이 경우에는 내 CPU %)에서 받고있는 원시 데이터의 연속 스트림에서 필터 (예 : 가우스 필터 또는 유사)를 실행하려고합니다.연속 스트리밍 데이터를 필터링 (매끄럽게)하는 가장 효율적인 방법은 무엇입니까

데이터 값 컬렉션은 n 엘리먼트입니다. 이 코드 조각이 실행될 때마다 새로운 cpu 값이 추가되고 가장 오래된 것을 제거하여 n 길이의 콜렉션을 본질적으로 deque([float('nan')] * n, maxlen=n)n이 그래프의 길이로 유지합니다.

다음 가우시안 필터를 통해 전체 컬렉션을 필터링하여 평활화 된 데이터 포인트를 만든 다음 플롯하여 컴퓨터에서 대부분의 시스템 모니터 cpu % 그래프와 유사한 애니메이션 그래프를 만듭니다.

이것은 잘 작동합니다 ... 그러나 새로운 데이터 값이 추가 될 때마다 전체 데이터 세트에서 필터를 실행하는 대신 들어오는 데이터를 필터링하는보다 효율적인 방법이 있어야합니다 (그래프 업데이트 매 2 초마다)

나는 전체 목록을 필터링하지 않고 그것을 할 수있는 방법을 생각할 수 있지만, 그것들은 매우 효율적인지 확신 할 수 없다. 거기서 저를 위해 작동 할 신호 처리 세계에서 무엇이 있습니까? 사과는 나의 설명이 약간 혼란 스럽다면, 나는 이것에 대해 아주 새로운 것이다.

from scipy.ndimage.filters import gaussian_filter1d 

# Not my actual code but hopefully describes what im doing 
def animate(): # function that is called every couple of milliseconds to animate the graph 
    # ... other stuff 
    values.append(get_new_val) # values = collection of data vals from cpu 
    line.set_ydata(gaussian_filter1d(values, sigma=4)) # line = the line object used for graphing 
    # ... other stuff 
    graph_line(line) # function that graphs the line 

tl; dr : 매 패스마다 전체 데이터 세트를 필터링하는 대신 원시 스트리밍 데이터를 매끄럽게 만드는 최적의 방법을 찾고 있습니다.

+0

오버랩 버퍼를 살펴보십시오. wikipedia의 [Overlap-add] (https://en.wikipedia.org/wiki/Overlap-add_method) 및 [scipy spectral] (https://docs.scipy.org) /doc/scipy/reference/signal.html#spectral-analysis) 함수는'noverlap'을 사용합니다. – denis

답변

1

필자는 한번도 사용해 본 적이 없지만, 당신이 필요로하는 것은 Savitzky–Golay filter이 무엇인지 들린다. 로컬 평활화 필터는 데이터를보다 차별화 (차별화)하는 데 사용할 수 있습니다.

좋은 소식은 버전 0.14 현재 scipy supports this filter입니다. 문서의 관련 부분 :

scipy.signal.savgol_filter(x, window_length, polyorder, deriv=0, delta=1.0, axis=-1, mode='interp', cval=0.0) 

    Apply a Savitzky-Golay filter to an array. 
    This is a 1-d filter. If x has dimension greater than 1, axis determines the axis along which the filter is applied. 
    Parameters: 

    x : array_like 
     The data to be filtered. If x is not a single or double precision floating point array, it will be converted to type numpy.float64 before ftering. 
    window_length : int 
     The length of the filter window (i.e. the number of coefficients). window_length must be a positive odd integer. 
    polyorder : int 
     The order of the polynomial used to fit the samples. polyorder must be less than window_length. 
    [...] 

나는 다항식 순서와 창 크기의 작은 쌍을 먼저 결정할 것입니다. 전체 n 데이터 포인트로 작업하는 대신 훨씬 작은 deque (약 window_length)의 매끄러 운 작업 만하면됩니다. 새로운 데이터 포인트가 생길 때마다 작은 deque에 추가하고, Savitzky-Golay 필터를 적용하고, 필터링 된 새 포인트를 가져 와서 그래프에 추가해야합니다.

그러나이 방법은 데이터 집합의 가장자리에 있지 않을 때 대부분 잘 정의 된 것으로 보입니다. 이는 정확성을 위해 몇 가지 측정 지연을 도입해야한다는 것을 의미 할 수 있습니다. 따라서 주어진 창 내부에있는 점을 항상 사용할 수 있습니다. 즉, 주어진 시점에 대해 "향후" 신뢰할 수있는 필터링 된 값을 얻기위한 데이터 포인트). 귀하의 데이터가 매초 다섯 번씩 측정되는 것을 고려하면, 필요하다면 합리적인 타협이 될 수 있습니다.

관련 문제