如何使用 `np.fft.fft` 制作 PSD 图?

How to make a PSD plot using `np.fft.fft`?

我想使用 numpy.fft.fft 函数绘制信号的功率谱密度与频率的关系图。我想这样做,以便我可以在转换中保留复杂的信息并知道我在做什么,而不是依赖 numpy 提供的更高级别的函数(如 periodogram 函数) .我正在关注 Mathwork 关于使用 Matlab 的 fft 函数进行 PSD 分析的精彩页面:https://www.mathworks.com/help/matlab/ref/fft.html

在这个例子中,我希望 PSD 在我用来构造信号的频率处达到峰值,在这个例子中是 100。我使用 1000 个时间点和 100 个反时限单位的频率生成信号。我认为可以根据 [0, nt/2] 绘制 fft 幅度,并且峰值会出现在频率中能量最多的地方。当我这样做时,事情出了问题。我预计我的 PSD 会达到 100 的峰值。

如何使用 np.fft.fft 绘制频率与该频率中包含的能量的频谱密度图?

编辑

澄清一下,在我的真实问题中,我只知道我的特征频率远大于我的采样频率

import matplotlib.pyplot as plt
import numpy as np
t = np.arange(1000)
sp = np.fft.fft(np.sin(100 * t * np.pi))
trange = np.linspace(0, t[-1] / 2, t.size)
plt.plot(trange, np.abs(sp) / t.size)
plt.show()

这是我根据预期输出绘制的草图:

你的采样频率是多少?根据采样频率,您生成的这个序列可以表示无限数量的连续时间信号。 如采样定理所述,采样频率需要至少是最大信号频率的两倍,因此,使用 fs = 250Hz 并使用 10 秒的正弦,它变为:

import matplotlib.pyplot as plt
import numpy as np

fs = 250
t = np.arange(0, 10, 1/fs)
sp = np.fft.fft(np.sin(2*np.pi * 100 * t))
trange = np.linspace(0, fs, len(t))
plt.plot(trange, np.abs(sp))
plt.show()

如果你运行这个你会看到预期的 100Hz 的峰值。