如果您检查Matlab的^{}函数返回的矩阵b,您将看到中心行与SciPy的savgol_coeffs返回的一维数组相同。b的上半部分和下半部分各有(framelen - 1)/2行,是要应用到信号末端的Savitzky-Golay滤波器的系数,其中滤波器是非对称的。也就是说,对于信号每一端的(framelen - 1)/2值,使用不同的一组系数来计算每个滤波值。在
您可以使用savgol_coeffs通过迭代pos参数来生成b。下面的ipython会话显示了一个示例。在In [74]: import numpy as np
In [75]: from scipy.signal import savgol_coeffs
In [76]: np.set_printoptions(precision=11, linewidth=90)
In [77]: order = 3
In [78]: windowlen = 5
这些是对称(即中心)Savitzky-Golay滤波器的系数。一维数组应与sgolay返回的矩阵的中心行匹配:
^{pr2}$
如果我们设置pos=windowlen-1,我们将得到在窗口一端计算滤波器的系数。它们应该与sgolay返回的数组的第一行相匹配:In [80]: savgol_coeffs(windowlen, order, pos=windowlen-1)
Out[80]: array([ 0.98571428571, 0.05714285714, -0.08571428571, 0.05714285714, -0.01428571429])
类似地,pos=0给出了窗口另一端的系数。它们应该与sgolay返回的矩阵的最后一行匹配:In [81]: savgol_coeffs(windowlen, order, pos=0)
Out[81]: array([-0.01428571429, 0.05714285714, -0.08571428571, 0.05714285714, 0.98571428571])
下面是与Matlab的sgolay的返回值匹配的完整数组:In [82]: b = np.array([savgol_coeffs(windowlen, order, pos=p) for p in range(windowlen-1, -1, -1)])
In [83]: b
Out[83]:
array([[ 0.98571428571, 0.05714285714, -0.08571428571, 0.05714285714, -0.01428571429],
[ 0.05714285714, 0.77142857143, 0.34285714286, -0.22857142857, 0.05714285714],
[-0.08571428571, 0.34285714286, 0.48571428571, 0.34285714286, -0.08571428571],
[ 0.05714285714, -0.22857142857, 0.34285714286, 0.77142857143, 0.05714285714],
[-0.01428571429, 0.05714285714, -0.08571428571, 0.05714285714, 0.98571428571]])
如果将其与Matlab中b = sgolay(3, 5)的结果进行比较,就会发现它们是相同的。在
要获得sgolay返回的g矩阵,必须调用savgol_coeffs,并将deriv设置为range(order+1)中的值,反转并转置数组,并按导数顺序的阶乘进行缩放。要反转系数,可以使用::-1形式的一部分,或者可以使用savgol_coeffs的use选项。在
下面是一种使用savgol_coeffs生成g矩阵的方法,其中order=3和{}:In [12]: import numpy as np
In [13]: from scipy.signal import savgol_coeffs
In [14]: from scipy.special import factorial
In [15]: np.set_printoptions(precision=11, linewidth=90, suppress=True)
In [16]: order = 3
In [17]: windowlen = 5
In [18]: g = np.array([savgol_coeffs(windowlen, order, deriv=d, use='dot') for d in range(order+1)]).T / factorial(np.arange(order+1))
In [19]: g
Out[19]:
array([[-0.08571428571, 0.08333333333, 0.14285714286, -0.08333333333],
[ 0.34285714286, -0.66666666667, -0.07142857143, 0.16666666667],
[ 0.48571428571, 0. , -0.14285714286, 0. ],
[ 0.34285714286, 0.66666666667, -0.07142857143, -0.16666666667],
[-0.08571428571, -0.08333333333, 0.14285714286, 0.08333333333]])
您不会说为什么要在Python中使用完整的windowlenxwindowlen数组。你不需要它来使用savgol_filter。在