使用Python计算给定信号的FFT,结果是否正确?
FFT结果正确性分析及修正方案
你的FFT结果不正确,问题出在采样参数的错误设定上,以下是具体分析和修正方案:
核心问题点
- 采样周期T设定错误:你硬编码了
T=1,但实际信号的采样间隔需要从CSV的时间列读取,而非假设为1秒。 - 样本数N设定错误:手动指定
N=100会截断或补零原始数据,导致频谱失真,应该用实际加载的信号数据长度。 - 未处理DataFrame格式问题:直接将Pandas DataFrame传入
fft可能引发维度错误,需转换为NumPy数组。
修正后的代码
import numpy as np import matplotlib.pyplot as plt import pandas as pd from scipy.fft import fft, fftfreq plt.rcParams['figure.dpi'] = 1000 # 加载数据集,读取时间和电压列 df = pd.read_csv('data/1.csv') time = df.iloc[:, 0].values # 第0列为时间(秒) voltage = df.iloc[:, 1].values # 第1列为电压 # 绘制原始信号 plt.figure() plt.plot(time, voltage) plt.xlabel('时间(秒)') plt.ylabel('电压') plt.title('原始信号') plt.show() # FFT计算 N = len(voltage) # 计算实际采样周期:相邻时间点的平均间隔 T = np.mean(np.diff(time)) # 生成正确的频率轴 freqs = fftfreq(N, T)[:N//2] # 去除直流分量 voltage_dc_removed = voltage - np.mean(voltage) # 执行FFT yf = fft(voltage_dc_removed) # 频谱幅度归一化(匹配原始信号振幅) amplitude = 2.0/N * np.abs(yf[:N//2]) # 绘制修正后的FFT结果 plt.figure() plt.plot(freqs, amplitude, label='信号频谱') plt.grid() plt.xlabel('频率(Hz)') plt.ylabel('频谱幅度') plt.legend(loc=1) plt.savefig('fft_corrected.jpg') plt.show()
修正说明
- 读取真实时间数据:从CSV中获取时间列,计算实际采样间隔
T,这是保证频率轴准确的核心。 - 使用
fftfreq生成频率轴:该函数会根据样本数和采样周期自动计算正确的频率值,避免手动计算误差。 - 频谱幅度归一化:乘以
2.0/N让频谱幅度与原始信号的振幅对应(直流分量除外)。 - 格式转换:将DataFrame转为NumPy一维数组,避免维度不匹配问题。
运行修正后的代码,你会得到与原始信号周期匹配的FFT频谱,峰值频率将对应原始信号的基频。
内容的提问来源于stack exchange,提问作者bardulia
相关产品推荐
相关产品推荐

