MATLAB在NumPy/Python中的平滑实现(n点移动平均)

rsn*_*een 2 python matlab numpy smooth scipy

smooth默认情况下,Matlab的功能使用5点移动平均值来平滑数据.在python中做同样的事情的最佳方法是什么?例如,如果这是我的数据

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
Run Code Online (Sandbox Code Playgroud)

平滑的数据应该是

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
Run Code Online (Sandbox Code Playgroud)

得到这个的Matlab语法是

smooth(data)
Run Code Online (Sandbox Code Playgroud)

我想在python中做同样的事情,但我找不到任何能做到这一点的函数.

Div*_*kar 11

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
...
Run Code Online (Sandbox Code Playgroud)

因此,为了在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  ))
Run Code Online (Sandbox Code Playgroud)