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

如何使用Python查找FFT频谱图峰值并获取对应x轴频率值

问题原因说明

  • 复数警告触发原因:scipy.signal.find_peaks 仅接受实值序列作为输入,而FFT运算的输出是包含实部、虚部的复数序列,直接传入会触发虚部丢弃的警告,也会导致峰值计算结果完全不符合预期。
  • 无法拿到正确x轴的原因:你当前用的x是原始数据的时域采样坐标,不是FFT变换后的频域频率坐标,需要单独生成对应的频率轴才能匹配峰值位置。

修复方案

  1. 对FFT的输出计算幅值(模值),再传入find_peaks做峰值检测
  2. 使用scipy.fft.fftfreq生成与FFT结果一一对应的频率轴,再根据峰值索引提取对应频率值
  3. 可选:仅保留正频率区间的结果,避免对称的重复峰值干扰

修正后代码

import pandas as pd
import matplotlib.pyplot as plt
from scipy.fft import fft, fftfreq
from scipy.signal import find_peaks
import numpy as np

headers = ["X","Y"]
original_data = pd.read_csv("testdata.csv",names=headers)

# 原始时域数据
t = original_data["X"]  # 这里是时域采样的时间/位置坐标
y = original_data["Y"]
n = len(y)
# 计算采样间隔
dt = t[1] - t[0]

# 执行FFT并计算幅值
y_fft = fft(y)
y_amp = np.abs(y_fft)  # 取模得到幅值,消除复数问题

# 生成对应频率轴
freq = fftfreq(n, dt)

# 仅保留正频率部分(可选,避免重复峰值)
positive_mask = freq >= 0
freq_pos = freq[positive_mask]
amp_pos = y_amp[positive_mask]

# 检测峰值,可根据需要调整height、threshold等参数筛选有效峰值
peaks_idx, _ = find_peaks(amp_pos)
# 提取峰值对应的频率和幅值
peak_freqs = freq_pos[peaks_idx]
peak_amps = amp_pos[peaks_idx]

print("峰值对应的频率值:", peak_freqs)
print("峰值对应的幅值:", peak_amps)

# 绘图
plt.plot(freq_pos, amp_pos)
plt.scatter(peak_freqs, peak_amps, color='red', label='检测到的峰值')
plt.title("Fast Fourier transform")
plt.xlabel("Frequency")
plt.ylabel("Amplitude")
plt.legend()
plt.show()

补充说明

如果需要筛选更精准的峰值,可以给find_peaks传入height(最小幅值阈值)、distance(峰值最小间隔)等参数,例如find_peaks(amp_pos, height=10, distance=5)可以过滤掉幅值低于10、间隔小于5个采样点的无效峰值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 11:36:01