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,則 a 和 b 都會被a[0]
正規化。- xarray_like
要過濾的資料陣列。
- axisint,可選
要將濾波器應用於 x 的軸。預設值為 -1。
- padtypestr 或 None,可選
必須為 'odd'、'even'、'constant' 或 None。這決定用於擴展填充訊號的類型,濾波器將應用於該訊號。如果 padtype 為 None,則不使用填充。預設值為 'odd'。
- padlenint 或 None,可選
在應用濾波器之前,在 axis 的兩端擴展 x 的元素數量。此值必須小於
x.shape[axis] - 1
。padlen=0
表示不填充。預設值為3 * max(len(a), len(b))
。- methodstr,可選
決定處理訊號邊緣的方法,可以是 “pad” 或 “gust”。當 method 為 “pad” 時,訊號會被填充;填充類型由 padtype 和 padlen 決定,並且 irlen 會被忽略。當 method 為 “gust” 時,將使用 Gustafsson 方法,並且 padtype 和 padlen 會被忽略。
- 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()
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 參數。y1 和 y2 之間的差異很小。對於長訊號,使用 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