基于Pandas DataFrame绘制FFT图表异常问题排查求助
FFT图表绘制异常排查与修复
问题概述
基于含时间和数值列的Pandas DataFrame绘制FFT图表时出现异常,表现为频谱曲线混乱、频率轴无实际参考价值。以下为原代码、样本数据:
原代码
import numpy as np import matplotlib.pyplot as plt import pandas as pd from scipy.fft import fftfreq plt.style.use("seaborn") data = pd.read_csv("/Users/kyungyunlee/Desktop/ IRP reference/Data/PIXEL_DATA/1_piece.csv") N = len(t) t = data["time"].loc[data["time"] > 5].loc[data["time"] < 10] s = data["y_value"].loc[data["time"] > 5].loc[data["time"] < 10] print(len(s)) fft = np.fft.fft(s) fftfreq = np.fft.fftfreq(len(s)) plt.subplot(1, 2, 1) plt.xlabel("Frquency Domain") plt.ylabel("Amplitude") plt.plot(fftfreq, fft) plt.subplot(1, 2, 2) plt.plot(t, s) plt.show()
样本数据
time,y_value 5.009026,614 5.035417,550 5.061302,554 ...(其余数据略)
异常原因分析
- 变量定义顺序错误:
N = len(t)写在t初始化之前,会触发未定义变量报错 - FFT结果未处理复数:
np.fft.fft()返回复数数组,直接绘图会导致曲线混乱,需取绝对值表示幅值 - 频率轴未匹配真实采样率:
fftfreq默认采样周期为1,未结合数据的实际时间间隔,导致频率刻度无实际意义 - 未过滤对称频谱:FFT结果是对称的,同时展示正负频率会造成图表冗余
- 未处理非均匀采样:原始时间序列可能是非均匀的,而FFT要求输入为均匀采样数据
修正后的代码
import numpy as np import matplotlib.pyplot as plt import pandas as pd plt.style.use("seaborn") # 读取并筛选数据 data = pd.read_csv("/Users/kyungyunlee/Desktop/ IRP reference/Data/PIXEL_DATA/1_piece.csv") filtered_data = data[(data["time"] > 5) & (data["time"] < 10)].copy() # 处理非均匀采样:插值为均匀时间序列 t_original = filtered_data["time"].values s_original = filtered_data["y_value"].values # 计算平均采样间隔,生成均匀时间轴 dt = np.mean(np.diff(t_original)) t_uniform = np.arange(t_original[0], t_original[-1], dt) # 线性插值得到均匀采样的信号值 s_uniform = np.interp(t_uniform, t_original, s_original) N = len(s_uniform) # 计算FFT并处理幅值与频率轴 fft_vals = np.fft.fft(s_uniform) fft_amp = np.abs(fft_vals) / N # 归一化幅值,匹配原始信号量级 freqs = np.fft.fftfreq(N, d=dt) # 基于真实采样间隔计算频率 # 筛选正频率部分,简化图表展示 positive_mask = freqs > 0 positive_freqs = freqs[positive_mask] positive_amp = fft_amp[positive_mask] # 绘图 plt.figure(figsize=(12, 5)) plt.subplot(1, 2, 1) plt.xlabel("Frequency (Hz)") plt.ylabel("Amplitude") plt.plot(positive_freqs, positive_amp) plt.title("FFT Spectrum") plt.subplot(1, 2, 2) plt.plot(t_uniform, s_uniform) plt.xlabel("Time") plt.ylabel("y_value") plt.title("Uniformly Sampled Signal") plt.tight_layout() plt.show()
关键修复说明
- 调整变量定义顺序,先筛选数据再计算序列长度
- 对FFT结果取绝对值并归一化,得到与原始信号匹配的幅值
- 结合数据的实际时间间隔计算频率轴,确保刻度准确反映真实频率
- 仅展示正频率部分,避免频谱对称重复造成的混乱
- 通过插值将非均匀采样数据转换为均匀采样序列,满足FFT的输入要求
内容的提问来源于stack exchange,提问作者Kyungyun
相关产品推荐
相关产品推荐

