使用Scipy.filtfilt处理数据时,如何减少一阶低通滤波器的边界异常?

新手上路,请多包涵

我正在学习信号处理,试图用python模拟一个一阶低通滤波器,如下差分方程:(1+ω)y[n]=x[n]+ωy[n-1] 其中 y [n] 表示输出,x [n] 表示输入。所以我尝试把这个滤波器与 Scipy.filtfilt 一起使用来处理数据,ω 为 5:

import scipy.signal as signal
import matplotlib.pyplot as plt

b = [1]
a = [6, -5]
#loading origin-CH1 0.txt
x = []
with open("origin'-CH1 20.txt", 'r') as f:
    for line in f:
        x.append(float(line))
y = signal.filtfilt(b=b, a=a, x=x,method='gust')

#writing output to origin-CH1 0.txt
with open("origin'--CH1 0.txt", 'w') as f:
    for i in y:
        f.write(str(i) + '\n')

#plot
plt.plot(y, label="After Filter", color='red')
plt.plot(x, label="Before Filter", color='blue',alpha=0.5)
plt.show()

但是非常奇怪的是在滤波后数据的起始/结尾段有一段明显的拉高/降低,如下图所示
image.png
image.png
这很奇怪。
原始数据:origin'-CH1 20.txt

试过减小 ω 的值,但似乎不太有用,并且滤波效果也会变差。

阅读 297
avatarAI BotBETA

要减少filtfilt的边界异常,关键是要处理好初始状态问题。以下是解决方案:

1. 修改代码(增加padlen参数):

y = signal.filtfilt(b=b, a=a, x=x, method='gust', padlen=150)  # 增加填充长度

2. 原理说明:

  • 根本原因是零相位滤波需要双向滤波,初始条件估计不准确会导致边界畸变
  • padlen参数控制前后填充的数据长度,通过延长填充让滤波器达到稳定状态
  • 建议值为数据长度的1%~5%(根据你的截图效果,建议150-200)

3. 附加优化建议:

# 方法1:镜像延拓预处理(手工实现)
pre_len = 100
x_ext = np.concatenate([2*x[0]-x[pre_len:0:-1], x, 2*x[-1]-x[-2:-pre_len-2:-1]])
y_ext = signal.filtfilt(b,a,x_ext, padlen=50)
y = y_ext[pre_len:-pre_len]

# 方法2:改用Butterworth滤波器(更稳定)
sos = signal.butter(1, Wn=5/(0.5*sample_rate), output='sos')  # 替换成实际采样率
y = signal.sosfiltfilt(sos, x)

4. 你的案例具体分析:

  • 原始差分方程正确转换:(1+ω)y[n] = x[n] + ωy[n-1] → 系数a=[6,-5]正确
  • ω=5对应截止频率:fc = 5/(2π(1+5)) ≈ 0.1326倍奈奎斯特频率
  • 当前参数理论稳定(极点z=5/6在单位圆内)

验证方法:

# 检查滤波器稳定性
from scipy.signal import tf2zpk
z, p, k = tf2zpk(b, a)
print("极点位置:", p)  # 应输出[0.8333],绝对值<1即稳定

建议优先尝试增大padlen参数,若仍不理想可结合镜像延拓预处理。若对相位无严格要求,也可考虑改用lfilter单次滤波。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏