You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于FFT的时间序列转频域代码修正咨询(采样率96000)

FFT频域转换代码修正方案

原代码核心问题

  • 频率轴(linspace)设置逻辑错误:混淆了采样率与数据长度的作用,频率范围和点数计算完全不符合频域分析规则
  • 幅值归一化错误:用采样率而非数据长度做归一化基准,且切片范围与频率轴不匹配
  • 绘图变量不一致:时域绘图未关联正确的信号数据,且时间与频率轴强行共享导致逻辑混乱

修正后的完整代码

import numpy as np
import matplotlib.pyplot as plt

# 假设time_series为你的时间序列信号,df为包含时间列的DataFrame
data = time_series
sample_length = len(data)
fs = 96000  # 采样率(Hz)

# 执行FFT变换
fft_result = np.fft.fft(data)

# 生成正确的频率轴:范围0到Nyquist频率(fs/2),点数对应正频率分量数量
freq_axis = np.linspace(0.0, fs/2, int(sample_length/2) + 1)

# 计算幅值并归一化:直流分量不加倍,其余正频率分量加倍(合并对称的负频率能量)
amplitude = np.abs(fft_result) / sample_length
amplitude[1:-1] *= 2  # 排除直流和Nyquist分量

# 提取正频率部分的幅值
pos_amplitude = amplitude[:int(sample_length/2) + 1]

# 绘图
fig, axs = plt.subplots(2, gridspec_kw={'hspace': 0.3})
plt.suptitle('时域与频域波形', fontsize=30)

# 时域波形图
axs[0].plot(df.iloc[:, 0], data)
axs[0].set_xlabel('时间', fontsize=20)
axs[0].set_ylabel('Q0', fontsize=20)

# 频域幅值图
axs[1].plot(freq_axis, pos_amplitude, color='g')
axs[1].set_xlabel('频率(Hz)', fontsize=20)
axs[1].set_ylabel('幅值', fontsize=20)

plt.show()

关键修正说明

  1. 频率轴计算
    频域分析中,有效频率范围是0到fs/2(Nyquist频率),频率点数量等于数据长度的一半加1(包含直流分量),确保与FFT正频率分量的数量完全匹配。

  2. 幅值归一化
    FFT结果的幅值需除以数据长度还原到原始信号的幅值量级,同时对除直流和Nyquist分量外的正频率分量乘以2,因为FFT结果中正负频率分量对称,我们仅保留正频率部分,需合并对应能量。

  3. 绘图逻辑优化
    取消时间轴与频率轴的共享(单位完全不同,无共享意义),同时明确时域绘图的时间列与信号数据的对应关系。

内容的提问来源于stack exchange,提问作者Aditya Bhandwalkar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 19:40:30