这里有几个建议。
首先,尝试
lowess
函数来自
statsmodels
具有
it=0
,然后调整
frac
参数一点:
In [328]: from statsmodels.nonparametric.smoothers_lowess import lowess
In [329]: filtered = lowess(pressure, time, is_sorted=True, frac=0.025, it=0)
In [330]: plot(time, pressure, 'r')
Out[330]: [<matplotlib.lines.Line2D at 0x1178d0668>]
In [331]: plot(filtered[:,0], filtered[:,1], 'b')
Out[331]: [<matplotlib.lines.Line2D at 0x1173d4550>]
第二个建议是使用
scipy.signal.filtfilt
而不是
lfilter
应用Butterworth滤波器。
filtfilt
是
向前向后
滤器它应用滤波器两次,一次向前,一次向后,导致零相位延迟。
这是您的脚本的修改版本。重要的变化是使用
过滤,过滤
而不是
硫过滤器
,以及
cutoff
从3000到1500。你可能想用这个参数进行实验——较高的值可以更好地跟踪压力增加的开始,但过高的值并不能过滤掉压力增加后3kHz(大致)的振荡。
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import butter, filtfilt
def butter_lowpass(cutoff, fs, order=5):
nyq = 0.5 * fs
normal_cutoff = cutoff / nyq
b, a = butter(order, normal_cutoff, btype='low', analog=False)
return b, a
def butter_lowpass_filtfilt(data, cutoff, fs, order=5):
b, a = butter_lowpass(cutoff, fs, order=order)
y = filtfilt(b, a, data)
return y
data = np.loadtxt('data.dat', skiprows=2, delimiter=',', unpack=True).transpose()
time = data[:,0]
pressure = data[:,1]
cutoff = 1500
fs = 50000
pressure_smooth = butter_lowpass_filtfilt(pressure, cutoff, fs)
figure_pressure_trace = plt.figure()
figure_pressure_trace.clf()
plot_P_vs_t = plt.subplot(111)
plot_P_vs_t.plot(time, pressure, 'r', linewidth=1.0)
plot_P_vs_t.plot(time, pressure_smooth, 'b', linewidth=1.0)
plt.show()
plt.close()
这是结果图。注意右边缘滤波信号的偏差。为了解决这个问题,您可以使用
padtype
和
padlen
的参数
过滤,过滤
或者,如果你知道你有足够的数据,你可以丢弃滤波信号的边缘。