我在NumPy中使用FFT函数进行一些信号处理。我有一个名为signal
的数组
每小时有一个数据点,总共有576个数据点。我在signal
上使用以下代码来查看其傅里叶变换。
t = len(signal)
ft = fft(signal,n=t)
mgft=abs(ft)
plot(mgft[0:t/2+1])
我看到两个峰值,但我不确定x轴的单位是什么,即它们如何映射到小时?任何帮助将不胜感激。
答案 0 :(得分:11)
鉴于采样率FSample
和变换块大小N
,您可以使用以下方法计算频率分辨率deltaF
,采样间隔deltaT
和总捕获时间capT
关系:
deltaT = 1/FSample = capT/N
deltaF = 1/capT = FSample/N
请注意,FFT会将值从0
返回到FSample
,或等效-FSample/2
到FSample/2
。在你的情节中,你已经将-FSample/2
放到了0
部分。 NumPy包含一个辅助函数来为您计算所有这些:fftfreq。
对于deltaT = 1 hour
和N = 576
的值,您获得deltaF = 0.001736 cycles/hour = 0.04167 cycles/day
,从-0.5 cycles/hour
到0.5 cycles/hour
。因此,如果您在bin 48(和bin 528)处具有幅度峰值,则对应于48*deltaF = 0.0833 cycles/hour = 2 cycles/day.
处的频率分量
通常,您应在计算FFT之前将window function应用于时域数据,以减少spectral leakage。汉恩窗口几乎从来都不是一个糟糕的选择。您还可以使用rfft
函数跳过输出的-FSample/2, 0
部分。那么,你的代码将是:
ft = np.fft.rfft(signal*np.hanning(len(signal)))
mgft = abs(ft)
xVals = np.fft.fftfreq(len(signal), d=1.0) # in hours, or d=1.0/24 in days
plot(xVals[:len(mgft)], mgft)
答案 1 :(得分:0)
fft变换的结果不会映射到HOURS,而是映射到数据集中包含的频率。拥有转换后的图形是有益的,这样我们就可以看到峰值的位置。
您可能在转换缓冲区的开头有尖峰,因为您没有进行任何窗口化。
答案 2 :(得分:0)
通常,来自FFT的频率的维度单位与归因于馈送到FFT的数据的采样率的维度单位相同,例如:每米,每弧度,每秒或在您的情况下,每小时。
每个FFT结果仓索引的频率缩放单位是N / theSampleRate,具有与上述相同的维度单位,其中N是完整FFT的长度(在这种情况下,您可能只绘制了这个长度的一半)严格的实际数据。)
请注意,每个FFT结果峰值bin表示带宽为非零的滤波器,因此您可能希望在映射到频率值的结果点上添加一些不确定性或误差范围。或者甚至使用插值估计方法,如果需要并且适合于源数据。