假设我们有一个数据集,大约可以由
import numpy as np
x = np.linspace(0,2*np.pi,100)
y = np.sin(x) + np.random.random(100) * 0.2
因此,我们有20%的数据集变异。我的第一个想法是使用scipy的UnivariateSpline函数,但是问题是这并没有很好地考虑小噪声。如果考虑频率,则背景比信号小得多,因此仅花键作为截止点可能是个主意,但这会涉及来回傅立叶变换,这可能会导致不良行为。
另一种方法是移动平均线,但这也需要正确选择延迟。
任何提示/书籍或链接如何解决此问题?
最佳答案
我更喜欢Savitzky-Golay filter。它使用最小二乘法将数据的一个小窗口回归到多项式上,然后使用多项式来估计窗口中心的点。最后,窗口向前移动一个数据点,然后重复该过程。这一直持续到每个点都相对于其相邻点进行了最佳调整为止。即使使用来自非周期性和非线性来源的嘈杂样本,它也能很好地工作。
这是一个thorough cookbook example。请参阅下面的代码,以了解它的易用性。注意:我省略了用于定义savitzky_golay()
函数的代码,因为您可以从上面链接的食谱示例中直接复制/粘贴它。
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0,2*np.pi,100)
y = np.sin(x) + np.random.random(100) * 0.2
yhat = savitzky_golay(y, 51, 3) # window size 51, polynomial order 3
plt.plot(x,y)
plt.plot(x,yhat, color='red')
plt.show()
更新:我注意到,我链接到的食谱示例已被删除。幸运的是,正如into the SciPy library所指出的,Savitzky-Golay过滤器已合并为@dodohjk。
要使用SciPy源修改以上代码,请输入:
from scipy.signal import savgol_filter
yhat = savgol_filter(y, 51, 3) # window size 51, polynomial order 3