Python中基于scipy实现快速傅里叶变换(FFT)时如何确定结果对应频率
scipy.fft.fft 输出对应的频率点计算规则
scipy.fft.fft 本身不会主动绑定采样相关的物理参数,它计算的离散傅里叶变换(DFT)的频率点完全由输入数组的长度和你自己定义的采样间隔两个参数决定,要拿到每个输出元素对应的实际频率,可以配合scipy自带的频率计算工具或者手动计算。
频率对应核心逻辑
- 设输入数组的长度为
n,两个相邻采样点的时间间隔为d(单位秒的话最终得到的频率单位为Hz),DFT输出的第k个索引(从0开始计数)对应的频率为f = k/(n*d) - 由于DFT的周期性特性,输出数组的后半段对应负频率区间,具体排布规则分两种情况:
- 当n为偶数时:前
n/2个元素对应0 ~ 1/(2d)的正频率区间,第n/2个元素对应奈奎斯特频率(采样率的一半),后n/2个元素对应-1/(2d) ~ -1/(n*d)的负频率区间 - 当n为奇数时:前
(n+1)/2个元素对应0 ~ (n-1)/(2*n*d)的正频率区间,后(n-1)/2个元素对应-(n-1)/(2*n*d) ~ -1/(n*d)的负频率区间
- 当n为偶数时:前
- 如果你使用的是针对实信号优化的
scipy.fft.rfft,由于实信号的DFT结果共轭对称,只会返回前半段非负频率的结果,长度为n//2 +1,不需要额外处理负频率部分
实际使用示例
你可以直接调用scipy.fft.fftfreq自动计算所有频率点,不需要手动推导:
import numpy as np from scipy.fft import fft, fftfreq # 定义采样参数:采样率1000Hz,采样间隔d=0.001s fs = 1000 d = 1 / fs # 生成长度为1000的输入信号 n = 1000 t = np.linspace(0, 1, n, endpoint=False) # 测试信号:100Hz正弦波 sig = np.sin(2 * np.pi * 100 * t) # 计算FFT结果 yf = fft(sig) # 计算每个FFT输出点对应的频率 xf = fftfreq(n, d) # 此时 yf[i] 就是频率 xf[i] 对应的变换结果
注意如果调用
fftfreq时不传入采样间隔d,默认值为1,得到的是归一化频率,需要乘以你的实际采样率才能得到物理单位的频率值。
内容的提问来源于stack exchange,提问作者Manish kumar gupta
相关产品推荐
相关产品推荐

