fft.fft()和ifft()是最常用函数,但需注意输入长度影响精度、补零提升分辨率、实信号用rfft()、频域滤波须fftshift/ifftshift配对、频率轴需手动计算且与采样间隔d相关、多维数组需显式指定axis。

fft.fft() 和 fft.ifft() 是最常用的一对函数,但输入长度影响结果精度
NumPy 的 fft.fft() 默认对整个数组第一轴做 DFT,返回复数数组。它不自动归一化,也不补零——这意味着如果输入长度不是 2 的整数次幂,计算仍能进行,但可能引入频谱泄漏或降低频率分辨率。
实操建议:
- 对信号做
fft.fft()前,优先用np.fft.fftshift()配合绘图,否则零频分量在左侧,不符合常规频谱图习惯 - 若需提升频率分辨率,应补零(
np.pad(arr, (0, N-len(arr)), 'constant')),而非插值;补零不增加信息量,但让频点更密 - 真实信号通常为实数,可用
fft.rfft()节省一半计算量和内存,对应逆变换用fft.irfft() - 注意
fft.ifft()返回仍是复数,即使原信号为实数,需用np.real()提取(或加np.round(..., decimals=12)消除数值噪声)
频域滤波时忘记用 fftshift 导致滤波器错位
直接对 fft.fft() 结果的前半段设为 0(比如想滤掉低频),会误删高频分量——因为未平移前,正频率和负频率是“折起来”的:索引 0 是 DC,1 到 N//2−1 是正频率,N//2 是 Nyquist,N//2+1 到 N−1 是负频率。
正确做法是先 fft.fftshift(),再操作中间区域:
freqs = np.fft.fftfreq(len(sig), d=dt) sig_fft = np.fft.fft(sig) sig_fft_shifted = np.fft.fftshift(sig_fft) # 现在 sig_fft_shifted[0] 对应最低负频,中间是 0Hz mask = np.abs(freqs) <p>漏掉 <code>ifftshift()</code> 这一步,会导致相位混乱,重构信号严重失真。</p><h3>采样率和频率轴必须手动算,fft.fftfreq() 不自动适配你的 dt</h3><p><code>fft.fftfreq(n, d=1.0)</code> 中的 <code>d</code> 是采样间隔(秒),不是采样率。常见错误是传入 <code>fs=1000</code>(采样率),却没转成 <code>d=1/1000</code>,结果频率轴整体缩放错 1000 倍。</p><div class="aritcle_card flexRow artxards"> <div class="artcardd flexRow"> <a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill11526" title="Python Hardener"><img src="https://img.php.cn/upload/skill/001/246/273/6adaf20dbae7c507.jpg" alt="Python Hardener" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a> <div class="aritcle_card_info flexColumn"> <a rel="nofollow" href="/xiazai/skill11526" title="Python Hardener" class="overflowclass">Python Hardener</a> <p class="overflowclass">通过完整的安全审查、代码整洁重构、健壮的错误处理、正确的日志记录以及完整的文档字符串覆盖,强化 Python 脚本。</p> </div> <a rel="nofollow" href="/xiazai/skill11526" title="Python Hardener" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a> </div> </div><p>使用场景中容易混淆的点:</p>
- 若你有时间数组
t = np.linspace(0, 1, 1000, endpoint=False),则d = t[1] - t[0],别硬写 0.001 -
fftfreq()返回的频率顺序与fft()输出一致(未 shift),而fftshift()后需用fft.fftshift(fftfreq(...))对齐 - 对于实信号用
rfft(),对应频率轴应改用fft.rfftfreq(n, d),它只返回非负频率(含 Nyquist),长度为n//2 + 1
fft 模块默认按行处理多维数组,跨轴操作要显式指定 axis
对二维信号(如多通道 EEG、图像行方向滤波),fft.fft() 默认作用于 axis=-1(即每行独立变换)。若想对列做 FFT(比如逐时间点跨通道分析),必须传 axis=0。
容易踩的坑:
- 忘记指定
axis导致维度错乱,例如arr.shape == (100, 512)(100 个通道 × 512 采样点),想对每个通道做 FFT,应写np.fft.fft(arr, axis=1),而非默认的axis=-1(此时也对 512 维做,结果一样,但语义模糊) - 使用
fft.fft2()或fft.fftn()时,若只希望某几个轴参与,需用axes参数,如fft.fftn(arr, axes=(0, 2)) - 广播操作(如乘滤波器)前务必确认变换轴与滤波器维度对齐,否则触发
ValueError: operands could not be broadcast together
离散傅里叶变换本身不难调用,真正卡住人的永远是频率轴理解、shift/unshift 配对、以及多维数据中 axis 的隐式假设——这些地方一旦出错,结果看起来“差不多”,但实际相位全毁,滤波完全失效。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










