當前位置: 首頁>>代碼示例 >>用法及示例精選 >>正文


Python SciPy signal.filtfilt用法及代碼示例


本文簡要介紹 python 語言中 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,) 數組

濾波器的分子係數向量。

a (N,) 數組

濾波器的分母係數向量。如果a[0]不是 1,那麽兩者都是ab歸一化a[0].

x array_like

要過濾的數據數組。

axis 整數,可選

應用過濾器的 x 軸。默認值為 -1。

padtype str 或無,可選

必須是‘odd’, ‘even’, ‘constant’,或無。這決定了用於應用濾波器的填充信號的擴展類型。如果 padtype 為 None,則不使用填充。默認值為‘odd’。

padlen int 或無,可選

要擴展的元素數x在兩端在應用過濾器之前。該值必須小於x.shape[axis] - 1.padlen=0意味著沒有填充。默認值為3 * max(len(a), len(b)).

method str,可選

確定處理信號邊沿的方法,“pad” 或“gust”。當method為“pad”時,信號被填充; padding的類型由padtype和padlen決定,irlen被忽略。當method為“gust”時,使用Gustafsson的方法,忽略padtype和padlen。

irlen int 或無,可選

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

返回

y ndarray

與 x 形狀相同的過濾輸出。

注意

什麽時候方法是“pad”,該函數以三種方式之一沿給定軸填充數據:奇數、偶數或常數。奇數和偶數擴展關於數據的端點具有相應的對稱性。常量擴展使用端點處的值擴展數據。在前向和後向傳播中,通過使用找到過濾器的初始條件scipy.signal.lfilter_zi並通過擴展數據的端點對其進行縮放。

什麽時候方法是“gust”,Gustafsson 的方法[1]用來。為前向和後向傳遞選擇初始條件,以便forward-backward 過濾器給出與backward-forward 過濾器相同的結果。

在 scipy 版本 0.16.0 中添加了使用 Gustaffson 方法的選項。

參考

[1]

F. Gustaffson,“確定forward-backward 過濾中的初始狀態”,信號處理事務,卷。 46,第 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

現在創建一個截止值為奈奎斯特頻率 0.125 倍(即 125 Hz)的低通巴特沃斯濾波器,並將其應用於 xfiltfilt 。結果應約為 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()

申請filtfiltsig,一次使用 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()
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 參數。 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

相關用法


注:本文由純淨天空篩選整理自scipy.org大神的英文原創作品 scipy.signal.filtfilt。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。