目录

  • 1、scipy.signal.filtfilt()函数介绍
  • 2、滤波器构造函数(巴特沃斯滤波器)
  • 3、如何进行高通、低通、带通、带阻滤波


1、scipy.signal.filtfilt()函数介绍

在信号的滤波过程中,因为scipy.signal.filtfilt()函数可以方便快捷得实现常见的多种滤波功能,所以有必要对其进行下较深入的了解和学习。

scipy.signal.filtfilt()滤波函数的语法:

filter_data=scipy.signal.filtfilt(b, a, x, axis=-1, padtype='odd', padlen=None, method='pad', irlen=None)

参数介绍:
b: 滤波器的分子系数向量;
a: 滤波器的分母系数向量;
x: 要过滤的数据数组;
axis: 指定要过滤的数据数组x的轴;
padtype: 必须是“奇数”、“偶数”、“常数”或“无”。这决定了用于过滤器应用的填充信号的扩展类型。{‘odd’, ‘even’, ‘constant’, None}
padlen:在应用滤波器之前在轴两端延伸X的元素数目。此值必须小于要滤波元素个数- 1。(int型或None)
method:确定处理信号边缘的方法。当method为“pad”时,填充信号;填充类型padtype和padlen决定,irlen被忽略。当method为“gust”时,使用古斯塔夫森方法,而忽略padtype和padlen。{“pad” ,“gust”}
irlen:当method为“gust”时,irlen指定滤波器的脉冲响应的长度。如果irlen是None,则脉冲响应的任何部分都被忽略。对于长信号,指定irlen可以显著改善滤波器的性能。(int型或None)
filter_data是经过滤波之后的数据结果

2、滤波器构造函数(巴特沃斯滤波器)

函数语法:

output_type=scipy.signal.butter(N, Wn, type='low', analog=False, output='ba')

语法参数介绍:
N:滤波器的阶数;
Wn:归一化截止频率。计算公式Wn=2*截止频率/采样频率;
type : 滤波器类型{‘lowpass’, ‘highpass’, ‘bandpass’, ‘bandstop’};
output : 输出类型{‘ba’, ‘zpk’, ‘sos’};
输出参数类型:
b,a: IIR滤波器的分子(b)和分母(a)多项式系数向量。output=‘ba’
z,p,k: IIR滤波器传递函数的零点、极点和系统增益. output= ‘zpk’
sos: IIR滤波器的二阶截面表示。output= ‘sos’

3、如何进行高通、低通、带通、带阻滤波

此处,我们以低通滤波器为例进行仿真实验,我们假设采样频率为1000hz,信号本身最大的频率为500hz,要滤除100hz以上频率成分,即截至频率为100hz,所以wn的计算为:wn=2*100/1000=0.2

高通滤波、带通滤波、带阻滤波在下面代码中也已经写出,其中的0.8在基于一个截至频率为400hz下进行计算得到的,wn2=2*400/1000=0.8

具体代码显示如下:

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

fname = os.path.join("D:\\Dataset", "s1.csv")
num= []

# 读取csv文件,并将对应数据写入num数组中
with open(fname, "r") as f1:
    data = f1.read()
    lines = data.split("\n")
    lines = lines[1:3000]
    for i in range(len(lines)):
        line_i = lines[i].split(",")
        num.append(int(line_i[4]))
        
# 构造巴特沃斯滤波器   
# 我们假设采样频率为1000hz,信号本身最大的频率为500hz,要滤除100hz以上频率成分,即截至频率为100hz,则wn=2*100/1000=0.2    
b, a = signal.butter(8, 0.2, 'lowpass')  # 配置滤波器 8 表示滤波器的阶数
#b, a = signal.butter(8, 0.2, 'highpass')  # 高通滤波:配置滤波器 8 表示滤波器的阶数
#b, a = signal.butter(8, [0.2,0.8], 'bandpass')   #带通滤波:配置滤波器 8 表示滤波器的阶数
#b, a = signal.butter(8, [0.2,0.8], 'bandstop')   #带阻滤波:配置滤波器 8 表示滤波器的阶数
# 使用滤波函数进行滤波操作
filtedData = signal.filtfilt(b, a, num)  # num为要过滤的信号

# 原始图像显示
plt.subplot(311)
plt.plot(num, linewidth=1)
# 滤波函数显示
plt.subplot(312)
plt.plot(filtedData, linewidth=1)
# 去除线性趋势的滤波函数显示
plt.subplot(313)
# scipy.signal.detrend()可以从信号中删除线性趋势
plt.plot(signal.detrend(filtedData), linewidth=1)
plt.show()

仿真结果显示为:

pyspark filter传函数 scipy filter_scipy


由此可见,低通滤波滤除掉了原始信号中大部分的毛刺和噪声,使原始信号得以平滑。

注:在上面仿真中的第三个图像,使用了signal中的detrend函数,使输入的信号经过函数处理后能够消除其线性的趋势。