振动数据集子集FFT计算输出为直线问题解决求助
问题根因
FFT输出为直线的核心原因是原始加速度信号包含较大的直流偏置(来自静态重力加速度分量),0Hz位置的幅值远高于其他频段的振动幅值,导致其他频率分量被压缩至纵轴接近0的位置,无法肉眼观测。
除此之外你的代码还存在两处可修复的问题:
- 未对信号做去直流预处理,直接输入原始信号计算FFT
- 生成秒级时间序列
t_sec时长度比x/y/z信号少1位,后续如果绘制时序图会出现长度不匹配报错
修复方案
- 计算FFT前对输入信号减去均值,去除直流偏置
- (可选)若需观察低幅值的高频分量,可将纵轴改为对数坐标显示
- 修正时间序列的长度错位问题
修改后的完整代码
import matplotlib.pyplot as plt import numpy as np from scipy.fftpack import fft from scipy import signal import tkinter as tk from tkinter import filedialog import time # 选择输入文件 root = tk.Tk() root.withdraw() file_path = filedialog.askopenfilename(filetypes=[("CSV File","*.csv")]) print(file_path) title = input("Enter Experiment Name: ") # 加载数据 tic = time.process_time() x, y, z, t = np.genfromtxt(file_path,delimiter=',', unpack=True) toc = time.process_time() print("Load Time:",toc-tic) # 计算信号参数 N = len(t) # 简化长度计算逻辑 dt = (t[1]-t[0])/10**9 # 时间戳转秒,计算采样间隔 Fs = 1/dt # 采样率 (Hz) total_duration = (t[-1] - t[0])/10**9 T = 1/Fs # 修正时间序列长度,和x/y/z保持一致 t_sec = (t - t[0])/10**9 print('Total Duration: ', total_duration) print("# Samples:",N) print('Sampling rate: ',Fs) # 计算并绘制FFT tic = time.process_time() plt.figure(figsize=(16,9)) xf = np.linspace(0.0, 1.0/(2.0*T), N//2) # *关键修改:对x信号去直流后再做FFT* yf = fft(x - np.mean(x)) yf_amp = 2.0/N * np.abs(yf[0:N//2]) plt.plot(xf, yf_amp) # 可选:开启对数纵轴,更方便观察低幅值分量 # plt.yscale('log') plt.grid() plt.xlabel('Frequency (Hz)', fontsize=14) plt.ylabel('Acc (m/$sec^2$)', fontsize=14) plt.title('FFT (X)- ' + title, fontsize=18) plt.savefig('FFT (X) {}'.format(title), dpi=300, bbox_inches='tight') plt.show() toc = time.process_time() print("FFT Compute & Plot Time:",toc-tic)
补充说明
如果仍有部分频段幅值过低无法观察,可取消代码中plt.yscale('log')的注释,使用对数纵轴展示幅值,即可同时观察到不同量级的频率分量。
内容的提问来源于stack exchange,提问作者Aayush Lakkad
相关产品推荐
相关产品推荐

