如何用Scipy FFT在相同频率范围下减少频域bin数量?
实现指定bin数量的FFT分析(保持窗口和频率范围)
首先明确:你完全可以减少bin数量,本质是对原始高分辨率FFT结果进行相邻bin的合并处理——示波器或频谱分析仪的类似功能,底层逻辑也是如此。
核心思路
原始FFT的分辨率由采样窗口长度决定:df = Fs / N = 40kHz / 1000 = 40Hz,对应501个bin(覆盖0到20kHz,包含Nyquist频率)。要得到80Hz间隔的bin(250/251个),只需将每两个相邻的40Hz原始bin合并为一个80Hz的新bin即可。
具体实现代码
import numpy as np from scipy.fft import rfft, rfftfreq # 假设sig是长度为1000的波形数组,替换为你的实际数据 sig = np.random.randn(1000) # 1. 计算原始FFT及频率点 sig_fft = rfft(sig) original_freqs = rfftfreq(1000, 1/40000) # 长度501:0,40,80,...,20000 sig_amp = np.abs(sig_fft) # 提取FFT幅值 # 2. 合并相邻bin得到80Hz间隔的结果 # 方式1:平均幅值(简单直观,符合你预期的峰值合并) # 前500个原始bin每2个合并,最后一个20kHz bin单独保留 merged_amp_avg = np.mean(sig_amp[:-1].reshape(-1, 2), axis=1) merged_amp_avg = np.append(merged_amp_avg, sig_amp[-1]) # 方式2:能量求和后开方(保持总能量守恒,更严谨) merged_amp_energy = np.sqrt(np.sum(np.square(sig_amp[:-1].reshape(-1, 2)), axis=1)) merged_amp_energy = np.append(merged_amp_energy, sig_amp[-1]) # 3. 生成对应的新频率点(0,80,160,...,20000) merged_freqs = original_freqs[::2] # 长度251,若要250个bin可去掉最后一个点:merged_freqs[:-1]
关键说明
- 合并逻辑:每两个40Hz的原始bin对应一个80Hz的新bin,覆盖的频率范围是
[k*80, (k+1)*80),幅值合并方式可根据需求选择(平均或能量守恒)。 - bin数量:如果严格要250个bin,只需去掉最后一个20kHz的点(
merged_amp_avg[:-1]),但会丢失Nyquist频率的信息;保留的话是251个bin,完整覆盖0-20kHz。 - 和仪器操作的对应:示波器/频谱分析仪中设置bin数,本质就是在底层执行类似的合并操作,将高分辨率FFT的相邻bin打包为更宽的分析单元。
内容的提问来源于stack exchange,提问作者eh_whatever
相关产品推荐
相关产品推荐

