numpy中信号的PSD及其缩放方法

3 投票
2 回答
18003 浏览
提问于 2025-04-18 06:12

我正在尝试计算并绘制一个随机信号的功率谱密度(PSD)。我查阅了numpy的文档,里面提到如果用A = fft(a)来表示傅里叶变换,那么np.abs(A)就是它的幅度谱,而np.abs(A)**2就是它的功率谱。

我的问题是,这个计算是否已经处理了必要的除法(通常在Matlab中需要自己做),比如说要根据箱子的数量等来正确缩放?

举个例子,如果x是我的原始信号,单位是伏特(V),然后我执行:

X = np.fft(x)
X = np.abs(X) #is that in Volts/Hz too? 
              #Do I have to divide by len(X) or anything else to scale it?
P = X**2      #is that in V^2/Hz? Do i have do do anything to scale it properly?

我觉得numpy的文档可以再详细一点。在Matlab中,我知道需要自己处理这些,但在numpy中情况如何呢?

2 个回答

2

scipy.signal.periodogram 这个函数会返回以 V**2/Hz 为单位的结果(假设你输入的是电压),而结果的区间则是以 Hz 为单位。

5

哎呀,"必要的除法"真让人头疼,但这是必须做的。关于功率谱密度的定义在不同领域之间差别很大,比如物理学和电气工程等。每个领域的定义都不一样,你得自己搞清楚想要的前因子(prefactor)。幸运的是,np.fft使用的约定在文档中有详细说明:

http://docs.scipy.org/doc/numpy/reference/routines.fft.html

我之前在自己的物理应用中也需要对numpy FFT的前因子进行大量调整。幸运的是,我可以确认文档是准确的。拿出纸和笔,祝你好运!

补充:对于你们提到的V / Hz和V^2 / Hz的问题,答案绝对是否定的。看看单位就知道了。如果你有一个电压的时间序列,它的(离散)傅里叶变换仍然是以伏特为单位的。你需要把时间步长等信息加上,才能得到想要的维度。我通常会先尝试从numpy FFT转到一个正式的(积分)傅里叶变换,这通常在你正在研究的理论工作中有定义。从那里开始通常会比较顺利。

补充 #2:为了后人参考,np.fft和matlab的fft是完全相同的,唯一的区别是前者是从零开始计数,后者是从一开始计数。所以如果你在matlab中有你想要的行为,是的,只需把你的除法和长度等操作带过来,就可以了。只要记住,在获取值或设置图表的x轴时,零频率在python中是A[0],而在matlab中是A(1)

撰写回答