SciPy "lfilter" 只返回 NaN
大家好,
我正在尝试使用SciPy的signal.lfilter
函数来过滤一组样本数据,但结果返回的全是NaN(不是一个数字)。
我已经绘制了滤波器的频率响应,滤波器的系数看起来是正确的;我很确定问题出在调用lfilter
这个函数上。
这是一个高通切比雪夫I型滤波器,我是这样创建的:
b,a = signal.iirdesign(wp = 0.11, ws= 0.1, gstop= 60, gpass=1, ftype='cheby1')
然后我用以下代码对数据进行过滤:
filtered_data = signal.lfilter(b, a, data)
下面,我打印了20个来自未过滤数据的样本,以及过滤后的数据。你可以清楚地看到问题所在:
### Printing a small selection of the data before it is filtered:
((-0.003070347011089325+0.0073614344000816345j), (-0.003162827342748642+0.007342938333749771j), (-0.003310795873403549+0.0073614344000816345j), (-0.0031813234090805054+0.007342938333749771j), (-0.003255307674407959+0.007398426532745361j), (-0.003162827342748642+0.007287450134754181j), (-0.003125835210084915+0.007509402930736542j), (-0.003162827342748642+0.007342938333749771j), (-0.0031073391437530518+0.007287450134754181j), (-0.0032368116080760956+0.007398426532745361j), (-0.0030888430774211884+0.007342938333749771j))
### Printing a small selection of the filtered data:
[ nan nanj nan nanj nan nanj nan nanj nan nanj nan nanj nan nanj
nan nanj nan nanj nan nanj nan nanj nan nanj nan nanj nan nanj
nan nanj nan nanj nan nanj nan nanj nan nanj nan nanj]
正如我之前所说,滤波器的系数看起来很好。它们是:
b = [ 4.06886235e-02 -7.73083846e-01 6.95775461e+00 -3.94272761e+01
1.57709105e+02 -4.73127314e+02 1.10396373e+03 -2.05021836e+03
3.07532754e+03 -3.75873366e+03 3.75873366e+03 -3.07532754e+03
2.05021836e+03 -1.10396373e+03 4.73127314e+02 -1.57709105e+02
3.94272761e+01 -6.95775461e+00 7.73083846e-01 -4.06886235e-02]
a = [ 1.00000000e+00 -1.27730099e+01 7.81201390e+01 -3.03738394e+02
8.40827723e+02 -1.75902089e+03 2.88045462e+03 -3.77173152e+03
3.99609428e+03 -3.43732844e+03 2.38415171e+03 -1.30118368e+03
5.21654119e+02 -1.18026566e+02 -1.85597824e+01 3.24205235e+01
-1.65545917e+01 5.02665439e+00 -9.09697811e-01 7.68172820e-02]
那么为什么lfilter
只返回NaN呢?我到底是怎么错误使用这个函数的呢?
提前谢谢你的帮助!
编辑:
好的,我解决了这个问题。
对于将来遇到这个问题的朋友们:
不知为什么,尽管滤波器返回的系数看起来不错,但当我在SciPy的lfilter
函数中使用这些系数时,过滤后的值却是无限的。只需将通带边缘改为任何一个不是0.11
的数字,就解决了这个问题。甚至这样也可以:
b,a = signal.iirdesign(wp = 0.119, ws= 0.1, gstop= 60, gpass=1, ftype='cheby1')
除了手动检查滤波器的极点和零点外,我不太确定如何检测滤波器的不稳定性。真是奇怪。
1 个回答
10
IIR滤波器是稳定的,当它的离散传递函数的分母根的绝对值都小于1时。也就是说,如果这些根的值都在-1到1之间,那么这个滤波器就是稳定的。你可以通过下面的代码来检查它是否稳定:
from scipy import signal
import numpy as np
b1, a1 = signal.iirdesign(wp = 0.11, ws= 0.1, gstop= 60, gpass=1, ftype='cheby1')
b2, a2 = signal.iirdesign(wp = 0.119, ws= 0.1, gstop= 60, gpass=1, ftype='cheby1')
print "filter1", np.all(np.abs(np.roots(a1))<1)
print "filter2", np.all(np.abs(np.roots(a2))<1)