2016-11-05 1530 views
2

Matlab的smooth函数默认情况下使用5点移动平均来平滑数据。在Python中做同样的事情最好的方法是什么? 例如,如果这是我的数据MATLAB在NumPy/Python中的平滑实现(n点移动平均)

0 
0.823529411764706 
0.852941176470588 
0.705882352941177 
0.705882352941177 
0.676470588235294 
0.676470588235294 
0.500000000000000 
0.558823529411765 
0.647058823529412 
0.705882352941177 
0.705882352941177 
0.617647058823529 
0.705882352941177 
0.735294117647059 
0.735294117647059 
0.588235294117647 
0.588235294117647 
1 
0.647058823529412 
0.705882352941177 
0.764705882352941 
0.823529411764706 
0.647058823529412 
0.735294117647059 
0.794117647058824 
0.794117647058824 
0.705882352941177 
0.676470588235294 
0.794117647058824 
0.852941176470588 
0.735294117647059 
0.647058823529412 
0.647058823529412 
0.676470588235294 
0.676470588235294 
0.529411764705882 
0.676470588235294 
0.794117647058824 
0.882352941176471 
0.735294117647059 
0.852941176470588 
0.823529411764706 
0.764705882352941 
0.558823529411765 
0.588235294117647 
0.617647058823529 
0.647058823529412 
0.588235294117647 
0.617647058823529 
0.647058823529412 
0.794117647058824 
0.823529411764706 
0.647058823529412 
0.617647058823529 
0.647058823529412 
0.676470588235294 
0.764705882352941 
0.676470588235294 
0.647058823529412 
0.705882352941177 
0.764705882352941 
0.705882352941177 
0.500000000000000 
0.529411764705882 
0.529411764705882 
0.647058823529412 
0.676470588235294 
0.588235294117647 
0.735294117647059 
0.794117647058824 
0.852941176470588 
0.764705882352941 

平滑的数据应该是

0 
0.558823529411765 
0.617647058823530 
0.752941176470588 
0.723529411764706 
0.652941176470588 
0.623529411764706 
0.611764705882353 
0.617647058823530 
0.623529411764706 
0.647058823529412 
0.676470588235294 
0.694117647058824 
0.700000000000000 
0.676470588235294 
0.670588235294118 
0.729411764705882 
0.711764705882353 
0.705882352941177 
0.741176470588235 
0.788235294117647 
0.717647058823529 
0.735294117647059 
0.752941176470588 
0.758823529411765 
0.735294117647059 
0.741176470588235 
0.752941176470588 
0.764705882352941 
0.752941176470588 
0.741176470588235 
0.735294117647059 
0.711764705882353 
0.676470588235294 
0.635294117647059 
0.641176470588236 
0.670588235294118 
0.711764705882353 
0.723529411764706 
0.788235294117647 
0.817647058823530 
0.811764705882353 
0.747058823529412 
0.717647058823530 
0.670588235294118 
0.635294117647059 
0.600000000000000 
0.611764705882353 
0.623529411764706 
0.658823529411765 
0.694117647058824 
0.705882352941176 
0.705882352941176 
0.705882352941176 
0.682352941176471 
0.670588235294118 
0.676470588235294 
0.682352941176471 
0.694117647058824 
0.711764705882353 
0.700000000000000 
0.664705882352941 
0.641176470588236 
0.605882352941177 
0.582352941176471 
0.576470588235294 
0.594117647058824 
0.635294117647059 
0.688235294117647 
0.729411764705882 
0.747058823529412 
0.803921568627451 
0.764705882352941 

在Matlab的语法来获得,这是

smooth(data) 

我想要做相同的蟒蛇,但我无法找到任何可以做到这一点的功能。

+0

这个问题是不是一样http://stackoverflow.com/questions/13728392/moving-average-or-磨合是什么意思? –

+0

@BillBell我不这么认为 – rsnaveen

+0

这里有一些其他的例子:http://scipy-cookbook.readthedocs.io/items/SignalSmooth.html – Moritz

回答

9

MATLAB的smoooth func基本上与滑动窗口长度为5的平均值相同,除了它在两端处理2个元素的方式。由于每个链接的文档,这些边界情况计算这些公式 -

yy = smooth(y) smooths the data in the column vector y .. 
The first few elements of yy are given by 

yy(1) = y(1) 
yy(2) = (y(1) + y(2) + y(3))/3 
yy(3) = (y(1) + y(2) + y(3) + y(4) + y(5))/5 
yy(4) = (y(2) + y(3) + y(4) + y(5) + y(6))/5 
... 

所以,要复制上与NumPy/Python的相同的实现,我们可以用NumPy's 1D convolution用于获取滑动窗口求和,并通过窗口长度将它们划分给我们的平均结果。然后,只需附加边界元素的特殊情况处理值即可。

因此,我们将不得不处理通用的窗口大小,像这样的实现 -

def smooth(a,WSZ): 
    # a: NumPy 1-D array containing the data to be smoothed 
    # WSZ: smoothing window size needs, which must be odd number, 
    # as in the original MATLAB implementation 
    out0 = np.convolve(a,np.ones(WSZ,dtype=int),'valid')/WSZ  
    r = np.arange(1,WSZ-1,2) 
    start = np.cumsum(a[:WSZ-1])[::2]/r 
    stop = (np.cumsum(a[:-WSZ:-1])[::2]/r)[::-1] 
    return np.concatenate(( start , out0, stop )) 
+0

非常感谢@Divakar。但是当我尝试使用函数'smooth'时出现以下错误:'AttributeError:'list'object has no attribute'cumsum'' – rsnaveen

+0

@rsnaveen我假设'a'是一个NumPy数组。修正它来处理数组和列表。 – Divakar

+0

非常感谢@Divakar。 – rsnaveen