我在MATLAB中有一个函数
[b,g] = sgolay(k, f);
输出f x f矩阵。
当我在Python中使用相同的k和f值运行时,使用:
scipy.signal.savgol_coeffs(f, k)
它输出一个完全不同的f元素数组。
考虑的值是:
k = 4,f = 21
savol_filter()
有三个参数,包括数组,而sgolay()
只有两个。此外,savo_coeffs
未生成所需的矩阵。
在matlab中获取由sgolay(k,f)生成的矩阵的Python等价物是什么?
答案 0 :(得分:0)
如果您检查了Matlab的sgolay
函数返回的矩阵b
,您会看到中心行与1相同sciPy savgol_coeffs
返回的-d数组。 b
的上半部分和下半部分,每个部分中有(framelen - 1)/2
行,是应用于信号末端的Savitzky-Golay滤波器的系数,其中滤波器不对称。也就是说,对于信号每端的(framelen - 1)/2
值,使用不同的系数集计算每个滤波值。
您可以通过迭代savgol_coeffs
参数来使用b
生成pos
。以下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滤波器的系数。 1-d数组应与sgolay
返回的矩阵的中心行匹配:
In [79]: savgol_coeffs(windowlen, order)
Out[79]: array([-0.08571428571, 0.34285714286, 0.48571428571, 0.34285714286, -0.08571428571])
如果我们设置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)
的结果进行比较,您会发现它们是相同的。
要获取g
返回的sgolay
矩阵,您必须在savgol_coeffs
设置为deriv
中的值时调用range(order+1)
,反转并转置数组,并按衍生顺序的阶乘进行缩放。要反转系数,您可以使用::-1
形式的切片,也可以使用use
的{{1}}选项。
这是使用savgol_coeffs
生成savgol_coeffs
矩阵与g
和order=3
的一种方法:
windowlen=5
你不能说出为什么你想在Python中使用完整的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]])
x windowlen
数组。您不需要它来使用windowlen
。