scipy.signal.welch中scaling参数spectrum与density的差异疑问
scipy.signal.welch的scaling参数差异及1.5倍系数来源说明
核心差异原理
你最初的推导默认对应矩形窗的场景,scipy的welch方法默认使用Hann(汉宁)窗,1.5倍系数完全来自该窗函数的能量校正特性:
scaling='density':输出功率谱密度,单位为信号单位平方/Hz,计算时引入窗函数的功率和作为校正项scaling='spectrum':输出功率谱,单位为信号单位平方,计算时引入窗函数的幅值和平方作为校正项
系数推导
设每段信号长度为nperseg=N,采样率为fs,频率分辨率为df = fs/N:
对于长度为N的Hann窗,两个关键统计量取值为:
- 窗函数幅值和 $S_1 = \sum_{n=0}^{N-1} w(n) = N/2$
- 窗函数功率和 $S_2 = \sum_{n=0}^{N-1} w(n)^2 = 3N/8$
代入两个scaling模式的输出比值公式spectrum / (density * df),可推导得:
$$\frac{spectrum}{density \times df} = \frac{N \times S_2}{S_1^2}$$
将Hann窗的S1、S2代入计算,结果为 $\frac{12}{8}=1.5$,和你实测的系数完全匹配。
验证方法
将窗口替换为矩形窗即可验证你最初的推导逻辑:
import numpy as np from scipy.signal import welch dt = 1/4 tt = np.arange(0,1000,dt) w = 1/5 data = 2 * np.sin(2*np.pi * w * tt) + np.random.normal(size = len(tt), scale = 1) # 替换窗函数为矩形窗(boxcar) ff_welch, spectrum = welch(data, nperseg = 250, fs = 1/dt, scaling = 'spectrum', window='boxcar') ff_welch, density = welch(data, nperseg = 250, fs = 1/dt, scaling = 'density', window='boxcar') df_welch = (ff_welch[1]-ff_welch[0]) test = spectrum / (density * df_welch)
运行后test的取值将为1,完全符合你最初的推测。
内容的提问来源于stack exchange,提问作者Olmo
相关产品推荐
相关产品推荐

