当每个窗口的点数均匀时,为什么matplotlib.mlab.psd和scipy.signal.welch的功率谱密度估计值会有所不同?

时间:2015-10-22 16:56:08

标签: python-2.7 scipy signal-processing discrete-mathematics mlab

matplotlib.mlab.psd(...)scipy.signal.welch(...)都实施了Welch的平均周期图方法来估算信号的功率谱密度(PSD)。假设将等效参数传递给每个函数,则返回的PSD应该是等效的。

然而,使用简单的正弦测试函数,当每个窗口使用的点数(nperseg的{​​{1}}关键字; scipy.signal.welch关键字时,两种方法之间存在系统差异for NFFT even ,如下所示,每个窗口64点的情况

even number of points per window

上图显示了通过两种方法计算的PSD,而下图显示了它们的相对误差(即两个PSD的绝对差除以它们的绝对平均值)。较大的相对误差表明两种方法之间存在较大的不一致。

当每个窗口使用的点数奇数时,这两个函数具有更好的一致性,如下所示相同的信号,但每个窗口处理65个点< / p>

odd number of points per window

在信号中添加其他特征(例如噪声)会稍微减少这种影响,但它仍然存在,当每个窗口使用偶数个点时,两种方法之间的相对误差约为10%。 (我意识到,对于每个窗口65个点计算的PSD的最高频率的相对误差相对较大。但是,这是在信号的奈奎斯特频率,并且我不太关心特征在如此高的频率下。当每个窗口的点数是偶数时,我更关心大部分信号带宽上的大而系统的相对误差。

这种差异是否有原因?一种方法在准确性方面是否优于另一种方法?我使用scipy版本0.16.0和matplotlib版本1.4.3。

用于生成上述图的代码如下所示。对于纯正弦信号,设置mlab.psd;对于有噪声的信号,将A_noise = 0设置为有限值。

A_noise

1 个答案:

答案 0 :(得分:8)

虽然参数可能看起来是等效的,但窗口参数对于偶数大小的窗口可能略有不同。更具体地说,除非提供特定的窗口向量,否则scipy的welch函数使用的窗口是用

生成的。
win = get_window(window, nperseg)

使用默认参数fftbins=True,并根据scipy documentation

  

如果为True,则创建一个“定期”窗口,准备与ifftshift一起使用,并乘以fft的结果(另请参见fftfreq)。

这导致生成的窗口长度均匀。从this section of the Window function entry on Wikipedia开始,与Matplotlib的window_hanning相比,这可以带来轻微的性能优势,它始终返回对称版本。

要使用相同的窗口,您可以明确指定两个PSD估计函数的窗口向量。例如,您可以使用以下方法计算此窗口:

win = scipy.signal.get_window('hanning',nperseg)

使用此窗口作为参数(在两个函数中都带有window=win)将给出以下图表,您可能会注意到两个PSD估计函数之间更接近的一致性:

PSD estimates

或者,假设您不想要周期性窗口属性,您也可以使用:

win = mlab.window_hanning(np.ones(nperseg)) # or
win = scipy.signal.get_window('hanning',nperseg,fftbins=False)