现有数据帧上的快速傅里叶变换显示出意想不到的结果
Fast Fourier Transforms on existing dataframe is showing unexpexted results
我有一个包含电压数据的 .csv
文件,当我绘制随时间变化的数据时,我可以看到它是频率为 60hz
的正弦波。
现在,当我尝试使用 scipy/numpy fft
模块执行 fft
时,我在接近 0
的频率处出现尖峰,而逻辑上它应该在 60
。 (如下图)
当我用在 python 中创建的正弦波进行尝试时,我得到了正确的结果,但我没有用我的实际数据得到它。
我在下面分享我的代码,如果我做错了什么请告诉我。提前致谢。
import csv
from matplotlib import pyplot as plt
import pandas as pd
import numpy as np
from scipy.fftpack import fft
from scipy.fftpack import fftfreq
df = pd.read_csv('Va_data.csv')
print(df.head())
N = df.shape[0]
frequency = np.linspace(0.0,100, int(N/2))
freq_data = fft(df['Va'])
y = (2/N)*np.abs(freq_data[0:np.int(N/2)])
plt.plot(frequency, y)
plt.title('Frequency Domain Signal')
plt.xlabel('Frequency in Hz')
plt.ylabel('Amplitude')
plt.show()
数据应该没问题,FFT 计算(直到常数)也应该没问题。它是关于如何绘制结果的。要使 x 轴值以赫兹表示频率信息,您需要
frequency = np.arange(N) / N * sampling_rate
然后你可以剪掉一半
frequency = frequency[:N//2]
交给plt.plot(frequency, y)
。上面 frequency
的等式来自这样一个事实,即 k = 0, .., N-1
的每个 DFT 系数 X(k)
都有一个 exp(-j 2pi kn/N)
,其中 k/N
给你归一化频率。乘以采样率恢复对应于连续域的频率。
样本:
# sample x data
xs = np.linspace(0, 4, 1_000)
# sampling rate in this case
fs = 1 / np.diff(xs)[0]
# sine of it
ys = np.sin(2 * np.pi * 60 * xs)
# taking FFT
dft = np.fft.fft(ys)
# getting x-axis values to represent freq in Hz
N = len(xs)
x_as_freq = np.arange(N) / N * fs
# now plotting it
plt.plot(x_as_freq, np.abs(dft))
plt.xlabel("Frequency (Hz)")
plt.ylabel("DFT magnitude")
# to see that peak is indeed at 60Hz
plt.xticks(np.arange(0, 250, 20))
这给出了
我有一个包含电压数据的 .csv
文件,当我绘制随时间变化的数据时,我可以看到它是频率为 60hz
的正弦波。
现在,当我尝试使用 scipy/numpy fft
模块执行 fft
时,我在接近 0
的频率处出现尖峰,而逻辑上它应该在 60
。 (如下图)
当我用在 python 中创建的正弦波进行尝试时,我得到了正确的结果,但我没有用我的实际数据得到它。
我在下面分享我的代码,如果我做错了什么请告诉我。提前致谢。
import csv
from matplotlib import pyplot as plt
import pandas as pd
import numpy as np
from scipy.fftpack import fft
from scipy.fftpack import fftfreq
df = pd.read_csv('Va_data.csv')
print(df.head())
N = df.shape[0]
frequency = np.linspace(0.0,100, int(N/2))
freq_data = fft(df['Va'])
y = (2/N)*np.abs(freq_data[0:np.int(N/2)])
plt.plot(frequency, y)
plt.title('Frequency Domain Signal')
plt.xlabel('Frequency in Hz')
plt.ylabel('Amplitude')
plt.show()
数据应该没问题,FFT 计算(直到常数)也应该没问题。它是关于如何绘制结果的。要使 x 轴值以赫兹表示频率信息,您需要
frequency = np.arange(N) / N * sampling_rate
然后你可以剪掉一半
frequency = frequency[:N//2]
交给plt.plot(frequency, y)
。上面 frequency
的等式来自这样一个事实,即 k = 0, .., N-1
的每个 DFT 系数 X(k)
都有一个 exp(-j 2pi kn/N)
,其中 k/N
给你归一化频率。乘以采样率恢复对应于连续域的频率。
样本:
# sample x data
xs = np.linspace(0, 4, 1_000)
# sampling rate in this case
fs = 1 / np.diff(xs)[0]
# sine of it
ys = np.sin(2 * np.pi * 60 * xs)
# taking FFT
dft = np.fft.fft(ys)
# getting x-axis values to represent freq in Hz
N = len(xs)
x_as_freq = np.arange(N) / N * fs
# now plotting it
plt.plot(x_as_freq, np.abs(dft))
plt.xlabel("Frequency (Hz)")
plt.ylabel("DFT magnitude")
# to see that peak is indeed at 60Hz
plt.xticks(np.arange(0, 250, 20))
这给出了