傅里叶平滑数据集

时间:2014-04-15 08:04:51

标签: python scipy fft smoothing

我正在关注this link来平滑我的数据集。 该技术基于去除信号的傅立叶变换的高阶项的原理,从而获得平滑的函数。 这是我的代码的一部分:

N = len(y)

y = y.astype(float)               # fix issue, see below
yfft = fft(y, N)

yfft[31:] = 0.0                   # set higher harmonics to zero
y_smooth = fft(yfft, N)

ax.errorbar(phase, y, yerr = err, fmt='b.', capsize=0, elinewidth=1.0)
ax.plot(phase, y_smooth/30, color='black') #arbitrary normalization, see below

然而有些事情不能正常运作。 实际上,您可以检查结果图: enter image description here 蓝点是我的数据,而黑线应该是平滑的曲线。

首先,我必须按照this discussion转换我的数据数组y

其次,我只是随意标准化以将曲线与数据进行比较,因为我不知道为什么原始曲线的值远远高于数据点。

最重要的是,曲线就像数据点的“镜面”,我不知道为什么会这样。 特别是第三点有一些建议会很棒,更常见的是如何使用这种技术优化我的特定数据集形状的平滑。

3 个答案:

答案 0 :(得分:7)

您的问题可能是由于标准FFT的移位造成的。你可以阅读它here.

您的数据是真实的,因此您可以利用FT中的对称性并使用特殊函数np.fft.rfft

x = np.arange(40)
y = np.log(x + 1) * np.exp(-x/8.) * x**2 + np.random.random(40) * 15
rft = np.fft.rfft(y)
rft[5:] = 0   # Note, rft.shape = 21
y_smooth = np.fft.irfft(rft)

plt.plot(x, y, label='Original')
plt.plot(x, y_smooth, label='Smoothed')
plt.legend(loc=0).draggable()
plt.show()

如果你绘制rft的绝对值,你会发现在5以上的频率中几乎没有信息,所以这就是我选择那个阈值的原因(以及一些玩法)。

结果如下:

enter image description here

答案 1 :(得分:1)

从我可以收集到的内容中,您希望通过执行以下操作来构建低通滤波器:

  1. 移至频域。 (傅里叶变换)
  2. 删除不需要的频率。
  3. 返回时区。 (逆傅里叶变换)
  4. 查看你的代码,而不是做3)你只是做另一个傅里叶变换。相反,尝试进行实际的逆傅立叶变换以回到时域:

    y_smooth = ifft(yfft, N)
    

    查看scipy signal以查看一堆已有的过滤器。

    (编辑:我很想看到结果,分享!)

答案 2 :(得分:0)

我会非常谨慎地使用这种技术。通过将 FFT 的频率分量归零,您可以在频域中有效地构建砖墙滤波器。这将导致在时域中与 sinc 进行卷积,并可能扭曲您想要处理的信息。查找“吉布斯现象”以获取更多信息。

您最好设计一个低通滤波器或使用一个简单的 N 点移动平均线(它本身就是一个 LPF)来完成平滑。