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,则 a 和 b 都将由a[0]
归一化。- x类似数组
要滤波的数据数组。
- 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]。为正向和反向传递选择初始条件,以便正向-反向滤波器给出与反向-正向滤波器相同的结果。
在 scipy 版本 0.16.0 中添加了使用 Gustaffson 方法的选项。
参考文献
[1]F. Gustaffson, “确定正向-反向滤波中的初始状态”,信号处理论文,第 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)的低通 Butterworth 滤波器,并使用
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