简体   繁体   English

在Python中使用低通黄油过滤器的Prolem

[英]Prolem with lowpass butter filter in Python

I wanted to filter (lowpass) a signal i have, and when it did not work, i started investigating why it wouldn't. 我想过滤(低通)我的信号,当它不起作用时,我开始研究为什么它不起作用。 I have made a few tests and i am somewhat surprised by the behavior of the butterworth filter. 我进行了一些测试,我对Butterworth过滤器的性能感到有些惊讶。 i have defined it like in this post 我已经在这篇文章中定义了它

def apply_filter(data, cutoff, fs, order=6, filter_type="low", analog=False):
    nyq = 0.5 * fs
    normalized_cutoff = cutoff / nyq
    b,a = butter(order, normalized_cutoff, btype=filter_type, analog=analog, output="ba")
    they = lfilter(b, a, data)
    return(they)

if i take a 1000 elements long sample, like so 如果我采用1000个元素长的样本,像这样

x = np.linspace(0, 2*np.pi, 1000)
y = np.sin(x) + 0.3* np.sin(10*x)
sampling_frequency = 1/ (x[-1] * 1e-3)
sampling_frequency
>> 159.15494309189532
# because i have 1000 thousand points for a "time" going up to 2 pi

plt.plot(x, y, x, apply_filter(y, cutoff=1, fs= sampling_frequency)

to which i get 我到了

这个

on the other hand, if i do the exact same thing but with a different number of points, say, 10000, i get a wrong result, and i don't quite understand why: 另一方面,如果我做完全相同的事情,但是分数不同,例如10000,我得到的结果是错误的,并且我不太明白为什么:

x = np.linspace(0, 2*np.pi, 10000)
y = np.sin(x) + 0.3* np.sin(10*x)
sampling_frequency = 1/ (x[-1] * 1e-4)
sampling_frequency
>> 1591.5494309189535
# because i have 10000 thousand points for a "time" going up to 2 pi

plt.plot(x, y, x, apply_filter(y, cutoff=1, fs= sampling_frequency)

and this time, i obtain 而这次,我得到

这个

which is obviously wrong. 这显然是错误的。 Can someone explain why would that happen? 有人可以解释为什么会这样吗? things seem to function alright for 1000 points or less... 事情似乎可以正常运行1000点或更少...

EDIT: 编辑:

I have plotted the frequency response of the filter, and the problem appears on these graphs, although i don't know why it does that either. 我已经画出了滤波器的频率响应,问题出现在这些图表上,尽管我也不知道为什么这么做。

sampling rate 
>> 159.1549430918953
b, a = butter(6, 1/(sampling_rate/2))
w, h = freqz(b, a, 8000)
plt.subplot(2,1,1)
plt.xlim(0, 15)
plt.plot(0.5*sampling_rate*w/np.pi, np.abs(h))

to which i get 我到了 这个

whereas, if i do 相反,如果我愿意

sampling_frequency *= 10
sampling_frequency
>> 1591.5494309189535
b, a = butter(6, 1/(sampling_rate/2))
w, h = freqz(b, a, 8000)
plt.subplot(2,1,1)
plt.xlim(0, 15)
plt.plot(0.5*sampling_rate*w/np.pi, np.abs(h))

then i get 然后我得到 这个

I feel like the function butterworth is having some trouble with a high number of points for some reason perhaps? 我觉得函数Butterworth可能由于某些原因在高分上遇到了麻烦?

thanks for your help! 谢谢你的帮助!

For whomever might be interested, this is actually a "known issue" with the butter filter used with the "ba" output. 对于可能感兴趣的人,这实际上是与“ ba”输出一起使用的黄油过滤器的“已知问题”。 You should rather use the "zpk" output instead, see this link . 您应该改为使用“ zpk”输出,请参阅此链接

You may use the "zpk" output in a rather simple way, very similar to what you would do with the "ba" output. 您可以以非常简单的方式使用“ zpk”输出,这与使用“ ba”输出非常相似。 This seems to work for as many as 1million points, no reason for it not to work further on. 这似乎可以工作多达100万个点,没有理由不继续工作。

here's a basic exemple: 这是一个基本的例子:

point_number=1000000
# our "data"
x = np.linspace(0, 2*np.pi, point_number)
y = sin(x) + 0.3* sin(10*x)

# sampling frequency would be 1/ sampling_time
sampling_frequency = point_number/(2*np.pi)
# hence the nyquist frequency
nyq = sampling_frequency/2
# desired cutoff frequency, in Hertz
cutoff = 1
# normalized for the function butter
normalized_cutoff = cutoff/nyq

z,p,k = butter(6, normalized_cutoff, output="zpk")
lesos = zpk2sos(z, p, k)
# filtered data
y_filtered_sos = sosfilt(lesos, y)

# plot part
plt.plot(x, y_filtered_sos, label="filtered data")
plt.title("filtered data, with zpk")
plt.plot(x,y, label="data")
plt.legend()
plt.title("filtered data, with zpk")

which gives 这使

这个

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM