使用Python的FFT - 意外的低频率

时间:2016-05-14 10:03:14

标签: python matplotlib scipy fft

我还在尝试使用Python中的FFT对此data进行频率分析。 采样率是每分钟1个数据点。

我的代码是:

from scipy.fftpack import fft
df3 = pd.read_csv('Pressure - Dates by Minute.csv', sep=",", skiprows=0)
df3['Pressure FFT'] = df3['ATMOSPHERIC PRESSURE (hPa) mean'] - df3['ATMOSPHERIC PRESSURE (hPa) mean'].mean()
Pressure = df3['Pressure FFT']
Fs = 1/60
Ts = 1.0/Fs
n = len(Pressure)
k = np.arange(n)
T = n/Fs
t = np.arange(0,1,1/n) # time vector
frq = k/T # two sides frequency range
frq = frq[range(int(n/2))] # one side frequency range

Y = np.fft.fft(Pressure)/n # fft computing and normalization
Y = Y[range(int(n/2))]

fig, ax = plt.subplots(2, 1)
ax[0].plot(t,Pressure)
ax[0].set_xlabel('Time')
ax[0].set_ylabel('Amplitude')
ax[1].plot(frq,abs(Y),'r') # plotting the spectrum
ax[1].set_xlabel('Freq (Hz)')
ax[1].set_ylabel('|Y(freq)|')

但结果给出了:

enter image description here

所以我的问题是:

1)为什么根本没有频率?数据显然是周期性的。

2)为什么频谱如此之低? (0 - 0.009)

3)也许我应该尝试不同的过滤技术?

任何见解?

谢谢!

2 个答案:

答案 0 :(得分:2)

  

1)为什么根本没有频率?数据显然是周期性的。

嗯,有频率内容,由于它的结构,它不完全可见。尝试更改绘制频谱的线,从ax[1].plot(frq,abs(Y),'r')ax[1].semilogy(frq,abs(Y),'r')

这将导致:

semilog Spectrum

我们现在应用了一个简单的转换,可以提升低值并限制高值。有关详细信息,请参阅this link。当然,删除DC(正如您在代码的第3行所做的那样)也有帮助。

这仍然看起来有点模糊,但如果我们放大到光谱的下半部分,我们就会看到:

semilog Transform

显示大约2.3e-05 Hz的尖峰,相当于大约12小时。

  

2)为什么频谱如此之低? (0 - 0.009)

因为您每60秒采样一次,因此您的采样频率(大约)为0.016 Hz。您的频谱包含DC(0Hz)和0.0083Hz之间的所有信号。有关详细信息,请参阅this link

  

3)也许我应该尝试不同的过滤技术?

如果您无法解决谐波问题,可以尝试开窗,但此处看起来并不像这样。

希望这有帮助。

答案 1 :(得分:1)

这些频率看起来如此之低的部分原因是因为振幅图中的时间轴被奇怪地缩放。如果你真的每60秒有一个样本,那么x轴的范围应该是0到1690260秒(即~20天!)。

enter image description here

通过眼睛,你似乎每50000秒(每天约2次)有一个小峰值,这相当于大约2x10 -6 Hz的频率。因此,考虑到x轴的大小,你的周期图看起来非常合理。