scipy.signal.

filtfilt#

scipy.signal.filtfilt(b, a, x, axis=-1, padtype='odd', padlen=None, method='pad', irlen=None)[原始碼]#

向前和向後將數位濾波器應用於訊號。

此函數應用線性數位濾波器兩次,一次向前,一次向後。組合濾波器具有零相位和兩倍於原始濾波器的濾波器階數。

此函數提供處理訊號邊緣的選項。

對於大多數濾波任務,應優先使用函數 sosfiltfilt(以及使用 output='sos' 的濾波器設計)而不是 filtfilt,因為二階區段的數值問題較少。

參數:
b(N,) array_like

濾波器的分子係數向量。

a(N,) array_like

濾波器的分母係數向量。如果 a[0] 不是 1,則 ab 都會被 a[0] 正規化。

xarray_like

要過濾的資料陣列。

axisint,可選

要將濾波器應用於 x 的軸。預設值為 -1。

padtypestr 或 None,可選

必須為 'odd'、'even'、'constant' 或 None。這決定用於擴展填充訊號的類型,濾波器將應用於該訊號。如果 padtype 為 None,則不使用填充。預設值為 'odd'。

padlenint 或 None,可選

在應用濾波器之前,在 axis 的兩端擴展 x 的元素數量。此值必須小於 x.shape[axis] - 1padlen=0 表示不填充。預設值為 3 * max(len(a), len(b))

methodstr,可選

決定處理訊號邊緣的方法,可以是 “pad” 或 “gust”。當 method 為 “pad” 時,訊號會被填充;填充類型由 padtypepadlen 決定,並且 irlen 會被忽略。當 method 為 “gust” 時,將使用 Gustafsson 方法,並且 padtypepadlen 會被忽略。

irlenint 或 None,可選

method 為 “gust” 時,irlen 指定濾波器的脈衝響應長度。如果 irlen 為 None,則不會忽略脈衝響應的任何部分。對於長訊號,指定 irlen 可以顯著提高濾波器的效能。

返回:
yndarray

x 具有相同形狀的已濾波輸出。

筆記

method 為 “pad” 時,函數會沿給定軸以三種方式之一填充資料:奇數、偶數或常數。奇數和偶數擴展在資料的端點附近具有相應的對稱性。常數擴展使用端點的值擴展資料。在正向和反向傳遞中,濾波器的初始條件是透過使用 lfilter_zi 並將其縮放到擴展資料的端點來找到的。

method 為 “gust” 時,將使用 Gustafsson 方法 [1]。為正向和反向傳遞選擇初始條件,以便正向-反向濾波器給出與反向-正向濾波器相同的結果。

使用 Gustaffson 方法的選項已在 scipy 版本 0.16.0 中新增。

參考文獻

[1]

F. Gustaffson,“Determining the initial states in forward-backward filtering”,Transactions on Signal Processing,Vol. 46,pp. 988-992,1996。

範例

範例將使用 scipy.signal 中的幾個函數。

>>> import numpy as np
>>> from scipy import signal
>>> import matplotlib.pyplot as plt

首先,我們建立一個一秒訊號,該訊號是兩個純弦波的總和,頻率分別為 5 Hz 和 250 Hz,以 2000 Hz 採樣。

>>> t = np.linspace(0, 1.0, 2001)
>>> xlow = np.sin(2 * np.pi * 5 * t)
>>> xhigh = np.sin(2 * np.pi * 250 * t)
>>> x = xlow + xhigh

現在建立一個低通 Butterworth 濾波器,其截止頻率為 Nyquist 頻率的 0.125 倍,或 125 Hz,並使用 filtfilt 將其應用於 x。結果應近似於 xlow,且沒有相位偏移。

>>> b, a = signal.butter(8, 0.125)
>>> y = signal.filtfilt(b, a, x, padlen=150)
>>> np.abs(y - xlow).max()
9.1086182074789912e-06

由於奇數擴展是精確的,並且具有適度長度的填充,因此對於此人工範例,我們得到了相當乾淨的結果,在達到實際資料時,濾波器的暫態效應已消散。一般而言,邊緣的暫態效應是不可避免的。

以下範例示範了選項 method="gust"

首先,建立一個濾波器。

>>> b, a = signal.ellip(4, 0.01, 120, 0.125)  # Filter to be applied.

sig 是要過濾的隨機輸入訊號。

>>> rng = np.random.default_rng()
>>> n = 60
>>> sig = rng.standard_normal(n)**3 + 3*rng.standard_normal(n).cumsum()

filtfilt 應用於 sig,一次使用 Gustafsson 方法,一次使用填充,並繪製結果以進行比較。

>>> fgust = signal.filtfilt(b, a, sig, method="gust")
>>> fpad = signal.filtfilt(b, a, sig, padlen=50)
>>> plt.plot(sig, 'k-', label='input')
>>> plt.plot(fgust, 'b-', linewidth=4, label='gust')
>>> plt.plot(fpad, 'c-', linewidth=1.5, label='pad')
>>> plt.legend(loc='best')
>>> plt.show()
../../_images/scipy-signal-filtfilt-1_00_00.png

irlen 參數可用於提高 Gustafsson 方法的效能。

估計濾波器的脈衝響應長度。

>>> z, p, k = signal.tf2zpk(b, a)
>>> eps = 1e-9
>>> r = np.max(np.abs(p))
>>> approx_impulse_len = int(np.ceil(np.log(eps) / np.log(r)))
>>> approx_impulse_len
137

將濾波器應用於較長的訊號,帶和不帶 irlen 參數。y1y2 之間的差異很小。對於長訊號,使用 irlen 可顯著提高效能。

>>> x = rng.standard_normal(4000)
>>> y1 = signal.filtfilt(b, a, x, method='gust')
>>> y2 = signal.filtfilt(b, a, x, method='gust', irlen=approx_impulse_len)
>>> print(np.max(np.abs(y1 - y2)))
2.875334415008979e-10