Python 中 FFT 峰值下的面积

Area under the peak of a FFT in Python

在继续通过 FFT 分析一​​些真实数据集之前,我尝试做一些测试,我发现了以下问题。

首先,我创建一个信号作为两个余弦之和,然后使用 rfft 进行转换(因为它只有实数值):

import numpy as np
import matplotlib.pyplot as plt
from scipy.fft import rfft, rfftfreq

# Number of sample points
N = 800
# Sample spacing
T = 1.0 / 800.0

x = np.linspace(0.0, N*T, N)
y = 0.5*np.cos(10*2*np.pi*x) + 0.5*np.cos(200*2*np.pi*x)

# FFT
yf = rfft(y)
xf = rfftfreq(N, T)

fig, ax = plt.subplots(1,2,figsize=(15,5))
ax[0].plot(x,y)
ax[1].plot(xf, 2.0/N*np.abs(yf))

从信号的定义中可以看出,我有两个振幅为 0.5、频率为 10 和 200 的振荡。现在,我希望 FFT 频谱在这些点上类似于两个增量,但显然增加频率会使峰变宽:

从第一个峰值可以推断振幅为0.5,但第二个不是。我尝试使用 np.trapz 获得峰值下的面积并将其用作振幅的估计值,但由于它接近狄拉克三角洲,它对我选择的间隔非常敏感。我的问题是我需要为我的数据分析获得尽可能准确的振幅。

编辑:因为它似乎与点数有关,所以我决定增加(现在我可以)采样频率。这样好像就解决了问题,如图所示:

然而,对于一定数量的点和采样频率,高频峰值变宽似乎仍然很奇怪...

不奇怪,你有频率仓泄漏。当您离散化傅里叶变换所需的信号(采样)时,将创建频率仓,这些频率仓是计算振幅的频率间隔。每个 bin 的宽度由 sample_rate / num_points 给出。因此,bin 的数量越少,为每个频率分配精确的振幅就越困难。选择最佳采样率时还存在其他问题,例如用于防止混叠的香农-奈奎斯特定理。 https://en.wikipedia.org/wiki/Nyquist%E2%80%93Shannon_sampling_theorem . But depending on the problem sometimes there some custom rates used for sampling. E.g. when dealing with audio a sampling rate of 44,100 Hz is widely used , cause is based on the limits of the human hearing. So it depends also on nature of the data you want to perform analysis as you wrote. Anyway , since this question has also theoretical value , you can also check https://dsp.stackexchange.com 一些有用的信息。

我想对乔治的回答发表评论,但我不能。

也许您的研究起点是离散傅里叶变换的属性。 时域中的信号实际上是余弦乘以方框 window,方框 window 转换为频域,作为 delta 与 sinc 函数的卷积。 sinc 函数会使频谱变模糊。

但是,我不确定我们在这里观察到频谱泄漏,因为 window 完全符合余弦的整个周期。箱子的离散化可能仍然在这里发挥作用。