scipy.signal.

週期圖#

scipy.signal.periodogram(x, fs=1.0, window='boxcar', nfft=None, detrend='constant', return_onesided=True, scaling='density', axis=-1)[source]#

使用週期圖估計功率譜密度。

參數:
xarray_like

量測值的時間序列

fsfloat, optional

x 時間序列的取樣頻率。預設值為 1.0。

windowstr 或 tuple 或 array_like, optional

想要使用的視窗。如果 window 是字串或 tuple,它會被傳遞給 get_window 以產生視窗值,預設為 DFT-even。請參閱 get_window 以取得視窗和所需參數的列表。如果 window 是 array_like,它將直接用作視窗,並且其長度必須等於計算週期圖的軸的長度。預設值為 ‘boxcar’。

nfftint, optional

使用的 FFT 長度。如果 None,將使用 x 的長度。

detrendstr 或 function 或 False, optional

指定如何去除每個區段的趨勢。如果 detrend 是字串,則會將其作為 type 參數傳遞給 detrend 函數。如果它是函數,它會接收一個區段並傳回一個去除趨勢的區段。如果 detrendFalse,則不進行去除趨勢處理。預設值為 ‘constant’。

return_onesidedbool, optional

如果 True,則針對實數資料傳回單邊頻譜。如果 False,則傳回雙邊頻譜。預設值為 True,但對於複數資料,始終傳回雙邊頻譜。

scaling{ ‘density’, ‘spectrum’ }, optional

選擇計算功率譜密度 (‘density’),其中 Pxx 的單位為 V**2/Hz,以及計算平方幅度譜 (‘spectrum’),其中 Pxx 的單位為 V**2(如果 x 以 V 為單位測量,且 fs 以 Hz 為單位測量)。預設值為 ‘density’

axisint, optional

計算週期圖的軸;預設值為最後一個軸 (即 axis=-1)。

傳回值:
fndarray

樣本頻率陣列。

Pxxndarray

x 的功率譜密度或功率譜。

另請參閱

welch

使用 Welch 方法估計功率譜密度

lombscargle

用於不均勻取樣資料的 Lomb-Scargle 週期圖

筆記

請查閱 頻譜分析 章節的 SciPy 使用者指南,以了解功率譜密度和幅度(平方)譜的縮放比例的討論。

在 0.12.0 版本中新增。

範例

>>> import numpy as np
>>> from scipy import signal
>>> import matplotlib.pyplot as plt
>>> rng = np.random.default_rng()

產生一個測試訊號,一個 1234 Hz 的 2 Vrms 正弦波,被 0.001 V**2/Hz 的白雜訊所破壞,並以 10 kHz 取樣。

>>> fs = 10e3
>>> N = 1e5
>>> amp = 2*np.sqrt(2)
>>> freq = 1234.0
>>> noise_power = 0.001 * fs / 2
>>> time = np.arange(N) / fs
>>> x = amp*np.sin(2*np.pi*freq*time)
>>> x += rng.normal(scale=np.sqrt(noise_power), size=time.shape)

計算並繪製功率譜密度。

>>> f, Pxx_den = signal.periodogram(x, fs)
>>> plt.semilogy(f, Pxx_den)
>>> plt.ylim([1e-7, 1e2])
>>> plt.xlabel('frequency [Hz]')
>>> plt.ylabel('PSD [V**2/Hz]')
>>> plt.show()
../../_images/scipy-signal-periodogram-1_00_00.png

如果我們平均頻譜密度的後半部分(以排除峰值),我們可以恢復訊號上的雜訊功率。

>>> np.mean(Pxx_den[25000:])
0.000985320699252543

現在計算並繪製功率譜。

>>> f, Pxx_spec = signal.periodogram(x, fs, 'flattop', scaling='spectrum')
>>> plt.figure()
>>> plt.semilogy(f, np.sqrt(Pxx_spec))
>>> plt.ylim([1e-4, 1e1])
>>> plt.xlabel('frequency [Hz]')
>>> plt.ylabel('Linear spectrum [V RMS]')
>>> plt.show()
../../_images/scipy-signal-periodogram-1_01_00.png

功率譜中的峰值高度是 RMS 振幅的估計值。

>>> np.sqrt(Pxx_spec.max())
2.0077340678640727