如何以正确的方式平滑曲线? [英] How to smooth a curve in the right way?

查看:128
本文介绍了如何以正确的方式平滑曲线?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们假设我们有一个数据集,大约可以由

Lets assume we have a dataset which might be given approximately by

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函数,但是问题是这并没有很好地考虑小噪声.如果考虑频率,则背景比信号小得多,因此仅花键作为截止点可能是个主意,但这会涉及来回傅立叶变换,这可能会导致不良行为. 另一种方法是移动平均线,但这也需要正确选择延迟.

Therefore we have a variation of 20% of the dataset. My first idea was to use the UnivariateSpline function of scipy, but the problem is that this does not consider the small noise in a good way. If you consider the frequencies, the background is much smaller than the signal, so a spline only of the cutoff might be an idea, but that would involve a back and forth fourier transformation, which might result in bad behaviour. Another way would be a moving average, but this would also need the right choice of the delay.

任何提示/书籍或链接如何解决此问题?

Any hints/ books or links how to tackle this problem?

推荐答案

我更喜欢 Savitzky-Golay过滤器.它使用最小二乘法将数据的一个小窗口回归到多项式上,然后使用多项式来估计窗口中心的点.最后,窗口向前移动一个数据点,然后重复该过程.这一直持续到每个点都相对于其相邻点进行了最佳调整为止.即使使用来自非周期性和非线性来源的嘈杂样本,它也能很好地发挥作用.

I prefer a Savitzky-Golay filter. It uses least squares to regress a small window of your data onto a polynomial, then uses the polynomial to estimate the point in the center of the window. Finally the window is shifted forward by one data point and the process repeats. This continues until every point has been optimally adjusted relative to its neighbors. It works great even with noisy samples from non-periodic and non-linear sources.

这是完整的烹饪书示例.请参阅下面的代码,以了解它的易用性.注意:我省略了用于定义savitzky_golay()函数的代码,因为您可以从上面链接的食谱示例中直接复制/粘贴它.

Here is a thorough cookbook example. See my code below to get an idea of how easy it is to use. Note: I left out the code for defining the savitzky_golay() function because you can literally copy/paste it from the cookbook example I linked above.

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过滤器, @dodohjk 指出,="="进入SciPy库. 要使用SciPy源修改上面的代码,请输入:

UPDATE: It has come to my attention that the cookbook example I linked to has been taken down. Fortunately, the Savitzky-Golay filter has been incorporated into the SciPy library, as pointed out by @dodohjk. To adapt the above code by using SciPy source, type:

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

这篇关于如何以正确的方式平滑曲线?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆