Python 平滑时间序列数据。

15

我在Python中有一些数据,格式为UNIX时间戳和数值:

[(1301672429, 274), (1301672430, 302), (1301672431, 288)...]

时间不断地递进一秒钟。我该如何减少这些数据,使得时间戳每秒钟出现一次,但数值是周围10个数值的平均值?

更高级的滚动平均值也很好,但这些数据被制成图表,主要是为了平滑图形。

在尝试使用SQL进行此操作会很麻烦后,我想跟进一下(TSQL Rolling Average of Time Groupings)。

2个回答

19

使用http://www.scipy.org/Cookbook/SignalSmooth

import numpy
def smooth(x,window_len=11,window='hanning'):
        if x.ndim != 1:
                raise ValueError, "smooth only accepts 1 dimension arrays."
        if x.size < window_len:
                raise ValueError, "Input vector needs to be bigger than window size."
        if window_len<3:
                return x
        if not window in ['flat', 'hanning', 'hamming', 'bartlett', 'blackman']:
                raise ValueError, "Window is on of 'flat', 'hanning', 'hamming', 'bartlett', 'blackman'"
        s=numpy.r_[2*x[0]-x[window_len-1::-1],x,2*x[-1]-x[-1:-window_len:-1]]
        if window == 'flat': #moving average
                w=numpy.ones(window_len,'d')
        else:  
                w=eval('numpy.'+window+'(window_len)')
        y=numpy.convolve(w/w.sum(),s,mode='same')
        return y[window_len:-window_len+1]

我使用以下代码得到了看起来很好的结果(尽管我不太理解其中的数学):

   if form_results['smooth']:
            a = numpy.array([x[1] for x in results])
            smoothed = smooth(a,window_len=21)
            results = zip([x[0] for x in results], smoothed)

2
如果你想要平均值,那么窗口应该是“平坦”的。其他的窗口协议会以不同的权重来加权窗口内的数据点。 - JoshAdel
1
如果使用Python 3,请确保将具有ValueErrors的行更改为: raise ValueError("smooth only accepts 1 dimension arrays.") - Femkemilene

1

我发现了Savitzky-Golay滤波器。它假设一个窗口并拟合多项式曲线,然后移动窗口。幸运的是,它在scipy中已经实现。

https://en.wikipedia.org/wiki/File:Lissage_sg3_anim.gif

使用这段代码:
from scipy.signal import savgol_filter
result = savgol_filter(value, 13, 5) # window size 13, polynomial order 5

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接