首页 > 解决方案 > Python中FFT峰值下的区域

问题描述

在继续通过 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并将其用作幅度的估计值,但由于它接近狄拉克增量,因此对我选择的间隔非常敏感。我的问题是我需要尽可能准确地获得幅度以进行数据分析。

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

具有更多点的 FFT

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

标签: pythonsignal-processingfft

解决方案


这并不奇怪,您有频率箱泄漏。当您离散傅里叶变换所需的信号(采样)时,会创建频率区间,这些频率区间是计算幅度的频率区间。每个 bin 都有宽度,由 sample_rate / num_points 给出。因此,bin 的数量越少,为每个频率分配精确的幅度就越困难。在选择最佳采样率方面存在其他问题,例如防止混叠的香农-奈奎斯特定理。https://en.wikipedia.org/wiki/Nyquist%E2%80%93Shannon_sampling_theorem. 但根据问题,有时会有一些用于采样的自定义速率。例如,在处理音频时,广泛使用 44,100 Hz 的采样率,原因是基于人类听力的限制。因此,它还取决于您在编写时要执行分析的数据的性质。无论如何,由于这个问题也具有理论价值,您还可以查看 https://dsp.stackexchange.com以获取一些有用的信息。


推荐阅读