对时间序列数据应用傅里叶变换并避免混叠

Posted

技术标签:

【中文标题】对时间序列数据应用傅里叶变换并避免混叠【英文标题】:Applying Fourier Transform on Time Series data and avoiding aliasing 【发布时间】:2019-04-09 02:10:28 【问题描述】:

我愿意对时间序列数据应用傅立叶变换,将数据转换为频域。我不确定我用来应用傅立叶变换的方法是否正确?以下是我使用过的数据的link。

读取数据文件后,我使用绘制了原始数据

t = np.linspace(0,55*24*60*60, 55)
s = df.values
sns.set_style("darkgrid")
plt.ylabel("Amplitude")
plt.xlabel("Time [s]")
plt.plot(t, s)
plt.show()

由于数据是每日频率,因此我使用 24*60*60 将其转换为秒数,并使用 55*24*60*60 将其转换为 55 天

图表如下:

接下来我使用下面的代码实现了傅里叶变换,得到的图像如下:

#Applying Fourier Transform
fft = fftpack.fft(s)

#Time taken by one complete cycle of wave (seconds)
T = t[1] - t[0] 

#Calculating sampling frequency
F = 1/T

N = s.size

#Avoid aliasing by multiplying sampling frequency by 1/2 
f = np.linspace(0, 0.5*F, N)

#Convert frequency to mHz
f = f * 1000

#Plotting frequency domain against amplitude
sns.set_style("darkgrid")
plt.ylabel("Amplitude")
plt.xlabel("Frequency [mHz]")
plt.plot(f[:N // 2], np.abs(fft)[:N // 2])  
plt.show()

我有以下问题:

我不确定我的上述方法对于实现傅立叶变换是否正确。

我不确定我用来避免混叠的方法是否正确。

如果,我所做的比如何解释频域图中的三个峰值是正确的。

最后,我将如何仅使用重要的频率来反转变换。

【问题讨论】:

【参考方案1】:

虽然我不会回答你的前两个问题(我觉得这看起来不错,但我希望专家的意见),但我可以权衡后两个问题:

如果,我所做的比如何解释频域图中的三个峰值是正确的。

嗯,这意味着您的信号有三个主要分量,频率大约为 0.00025 mHz(可能不是这里的最佳单位选择!)、0.00125 mHz 和 0.00275 mHz。

最后,我将如何仅使用重要的频率来反转变换。

您可以将低于您决定的截止频率的每个频率归零(例如,绝对值 3 - 这应该涵盖您的峰值)。然后你可以这样做:

below_cutoff = np.abs(fft) < 3
fft[below_cutoff] = 0
cleaner_signal = fftpack.ifft(fft)

应该这样做,真的!

【讨论】:

以上是关于对时间序列数据应用傅里叶变换并避免混叠的主要内容,如果未能解决你的问题,请参考以下文章

选带傅里叶变换(zoom-fft)

图片处理-opencv-12.图像傅里叶变换

音频算法入门-傅里叶变换

傅里叶变换与卷积的区别

傅里叶变换@(stft和istft)

opencv之傅里叶变换