我对傅立叶理论是陌生的,并且我看过非常好的教程,内容涉及如何将fft应用于信号并绘制信号以查看其包含的频率。不知何故,所有这些人都在创建自己的数据时混合了各种罪过,而我很难适应我的实际问题。
我每天进行242次每小时观测,这意味着我的周期是24。所以我希望在fft图上出现24左右的峰值。
我的data.csv示例在这里: https://pastebin.com/1srKFpJQ
绘制的数据:
我的代码:
data = pd.read_csv('data.csv',index_col=0)
data.index = pd.to_datetime(data.index)
data = data['max_open_files'].astype(float).values
N = data.shape[0] #number of elements
t = np.linspace(0, N * 3600, N) #converting hours to seconds
s = data
fft = np.fft.fft(s)
T = t[1] - t[0]
f = np.linspace(0, 1 / T, N)
plt.ylabel("Amplitude")
plt.xlabel("Frequency [Hz]")
plt.bar(f[:N // 2], np.abs(fft)[:N // 2] * 1 / N, width=1.5) # 1 / N is a normalization factor
plt.show()
这会输出一个非常奇怪的结果,似乎每个频率我都得到相同的值。
我想问题出在N,t和T的定义上,但是我找不到任何在线方法可以帮助我清楚地理解这一点。请帮忙:)
EDIT1:
使用查尔斯答案提供的代码,我在0附近有一个尖峰,这似乎很奇怪。我改用rfft
和rfftfreq
来避免频率过高。
我已经读到这可能是因为该系列的DC分量,所以在减去均值后,我得到:
我很难解释这个问题,峰值似乎是周期性发生的,但是以Hz为单位的值无法让我获得我的24值(总频率)。有人知道如何解释吗?我想念什么?
答案 0 :(得分:5)
您看到的问题是因为条形太宽,而您只看到一个条形。您必须将条形的宽度更改为0.00001或更小才能看到它们。
不要使用条形图,而是使用fftfreq = np.fft.fftfreq(len(s))
来设置x轴,然后使用绘图功能plt.plot(fftfreq, fft)
:
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
data = pd.read_csv('data.csv',index_col=0)
data.index = pd.to_datetime(data.index)
data = data['max_open_files'].astype(float).values
N = data.shape[0] #number of elements
t = np.linspace(0, N * 3600, N) #converting hours to seconds
s = data
fft = np.fft.fft(s)
fftfreq = np.fft.fftfreq(len(s))
T = t[1] - t[0]
f = np.linspace(0, 1 / T, N)
plt.ylabel("Amplitude")
plt.xlabel("Frequency [Hz]")
plt.plot(fftfreq,fft)
plt.show()