np.fft.fft(x) 返回与输入等长的复数数组,索引0为直流分量,1至n//2为正频率,n//2+1至n−1为负频率(共轭对称);需配合fftfreq生成频率轴、手动归一化及取单边谱才能获得物理可解释的幅度谱。

NumPy 的 fft 模块能直接做 FFT,但默认返回复数频谱,不加处理直接画图或取模会出错——这是新手最常卡住的地方。
用 np.fft.fft() 得到的是什么?
它返回长度相同的复数数组,索引 0 对应直流分量(均值),正频率从 1 开始到 n//2,负频率在后半段(对称)。如果你只想要单边幅度谱,不能直接用 abs() 后全留着,得切片 + 归一化。
-
np.fft.fft(x)不做任何缩放,能量不守恒;若需功率谱密度,得手动除以len(x)或sqrt(len(x)) - 实信号的 FFT 具有共轭对称性,
np.fft.fft(x)的后半段是前半段的镜像,一般只取前n//2 + 1点 - 若输入是浮点数组但精度不高(比如从文件读入带小误差的整数),
np.fft.fft()仍返回复数,虚部极小但非零
怎么得到正确的频率轴和幅度谱?
别手算 np.arange(n) * fs / n ——容易漏掉 np.fft.fftfreq() 这个专用函数。它自动处理采样率、长度,并按 FFT 输出顺序排好频率值。
- 用
freqs = np.fft.fftfreq(len(x), d=1/fs)得到与np.fft.fft(x)输出一一对应的频率数组 - 取单边谱:用
freqs[:len(freqs)//2+1]和np.abs(X)[:len(X)//2+1],注意长度奇偶会影响切点 - 若要归一化幅度(如近似真实幅值),对单边谱需将除直流和奈奎斯特点外的所有点 ×2
为什么 np.fft.ifft() 复原信号总带微小虚部?
这是浮点计算误差导致的,不是 bug。即使原始信号是纯实数,IFFT 结果的虚部通常在 1e-15 量级,直接 np.real() 就行,别用 np.abs() 或强制转 int。
- 安全写法:
np.real(np.fft.ifft(X)),或更稳妥地np.fft.ifft(X).real - 若之后还要做运算(如叠加、滤波),建议全程保持复数类型,直到最后输出才取实部
- 用
np.allclose(x, np.real(np.fft.ifft(np.fft.fft(x))))验证即可,别用==
FFT 的核心陷阱不在调用函数,而在频谱解释:频率轴是否对齐、幅度是否归一、双边/单边是否混淆、实部虚部是否误判——这些细节不手动验证,结果看着“有谱”但数值完全不可信。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











