python - 如何以正确的方式平滑曲线?

让我们假设我们有一个数据集,它可以近似地给出

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()

更新:我注意到我链接到的食谱示例已被删除。幸运的是,Savitzky-Golay 过滤器已被纳入 into the SciPy library ,正如 @dodohjk 所指出的那样(感谢 @bicarlsen 更新链接)。 要使用 SciPy 源修改上述代码,请键入:

from scipy.signal import savgol_filter
yhat = savgol_filter(y, 51, 3) # window size 51, polynomial order 3

https://stackoverflow.com/questions/20618804/

相关文章:

linux - 如何在 GNU/Linux 上设置 Subversion (SVN) 服务器 - U

python - 在 Python 脚本中,如何设置 PYTHONPATH?

unix - 创建守护进程时执行双叉的原因是什么?

python - 字典:获取键列表的值列表

python - isinstance ('aaa' , basestring) 和 isinsta

python - 如何处理boto3的错误?

linux - CURL 用于访问需要从其他页面登录的页面

linux - 使用 Git 保留文件权限

python - 如何在python中向后循环?

linux - 如何在 Linux 上的 Bash 中一次删除多个文件?