现有数据帧上的快速傅里叶变换显示出意想不到的结果

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()

Voltage data

数据应该没问题,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))

这给出了