使用numpy rfft绘制WAV文件频谱时遇维度不匹配问题求助
解决rfft绘制频谱时xf与yf长度不匹配的问题
嘿,我来帮你搞定这个rfft的小坑!你遇到的xf长度是yf一半的问题,核心原因是对rfft和rfftfreq的参数逻辑理解有点偏差,咱们一步步理清楚:
先搞懂rfft的本质
rfft是专门为实数信号(比如WAV音频)设计的FFT优化版本——因为实数信号的FFT结果是共轭对称的,负频率分量和正频率分量完全冗余,所以rfft直接只返回正频率部分(包含DC分量和Nyquist频率),输出的yf长度是 N//2 + 1,其中N是原始音频信号的总采样点数。
为什么xf和yf长度不匹配?
问题大概率出在rfftfreq的参数上!很多人会误以为要传入yf的长度,但实际上rfftfreq的第一个参数必须是原始信号的总采样点数N,而不是rfft输出的长度。
举个实际的代码例子,假设你加载的音频信号是audio_data,采样率是sample_rate:
import numpy as np from scipy.fft import rfft, rfftfreq import matplotlib.pyplot as plt # 假设已经加载了音频,audio_data是实数数组,sample_rate是采样率 N = len(audio_data) # 计算rfft结果 yf = rfft(audio_data) # 重点:rfftfreq的第一个参数是原始信号的采样点数N,不是len(yf)! xf = rfftfreq(N, 1 / sample_rate) # 现在检查长度:应该完全相等 print(f"xf长度: {len(xf)}, yf长度: {len(yf)}") # 输出应该是一致的
如果你之前错误地用了rfftfreq(len(yf), 1/sample_rate),那生成的xf长度会是(len(yf))//2 +1,而len(yf)本身是N//2 +1,自然就会出现xf长度约为yf一半的情况。
正确绘制频谱的步骤
修正参数后,就可以正常绘制音乐场景需要的正频率频谱了:
- 取
yf的幅度值(因为rfft输出是复数):amplitude = np.abs(yf) - 如果需要dB刻度(更符合人耳听觉特性):
db_amplitude = 20 * np.log10(amplitude / np.max(amplitude)) - 绘制时直接用
xf作为x轴,幅度值作为y轴:
plt.plot(xf, db_amplitude) plt.xlabel("Frequency (Hz)") plt.ylabel("Amplitude (dB)") plt.title("Audio FFT Spectrum (rfft)") plt.show()
这样绘制出来的频谱就是从0到sample_rate/2的正频率部分,完全满足音乐场景的需求,而且避免了常规FFT中负频率的冗余计算。
内容的提问来源于stack exchange,提问作者David Gash
相关产品推荐
相关产品推荐

