Python 如何获得链式IIR过滤器的b,a(分子/分母)?

Python 如何获得链式IIR过滤器的b,a(分子/分母)?,python,numpy,scipy,signal-processing,Python,Numpy,Scipy,Signal Processing,假设我们已经先后应用了3个过滤器: b, a = iirfilter(...) # or bilinear(...) or anything else producing b, a y = lfilter(b, a, x) b, a = iirfilter(...) y = lfilter(b, a, y) b, a = iirfilter(...) y = lfilter(b, a, y) 如何获得与3个过滤器等效的系数b2,a2,这样我们只需一次lfilter: y = lfilte

假设我们已经先后应用了3个过滤器:

b, a = iirfilter(...)  # or bilinear(...) or anything else producing b, a
y = lfilter(b, a, x)
b, a = iirfilter(...) 
y = lfilter(b, a, y)
b, a = iirfilter(...) 
y = lfilter(b, a, y)
如何获得与3个过滤器等效的系数
b2
a2
,这样我们只需一次
lfilter

y = lfilter(b2, a2, x)


编辑:卷积似乎不起作用:

fs = 44100
b2, a2 = iirfilter(2, 2.0/fs * np.asarray([40, 60]), btype='bandstop')  # 50 hz reject
b3, a3 = iirfilter(2, 2.0/fs * np.asarray([85, 115]), btype='bandstop')  # 100 hz reject
b = np.convolve(b2, b3)
a = np.convolve(a2, a3)
w, h = signal.freqz(b, a, worN=10000)
给出:

我尝试使用np.convolve的
相同的
完整的
有效的
参数,但没有一个解决问题。

请参阅

你可以分别卷积分子和分母

import scipy as sp
import scipy.signal as sig

# Individual filters
b1, a1 = sig.iirfilter(...)
b2, a2 = sig.iirfilter(...)

# Cascaded filter
a = sp.convolve(a1, a2)
b = sp.convolve(b1, b2)
y = sig.lfilter(b, a, x)
例如,给定的采样率太高,并且复合过滤器的阶数不够长,无法对接近的空值给出如此多的拒绝。降低采样率,然后向上插值44.1 kHz

以下是采样率降至4410 Hz的结果

fs = 4410.0
b2, a2 = sig.iirfilter(2, 2.0/fs * sp.asarray([40, 60]), btype='bandstop')  # 50 hz reject
w2, h2 = sig.freqz(b2, a2, worN=4096)

b3, a3 = sig.iirfilter(2, 2.0/fs * sp.asarray([85, 115]), btype='bandstop')  # 100 hz reject
w3, h3 = sig.freqz(b3, a3, worN=4096)

b = sp.convolve(b2, b3)
a = sp.convolve(a2, a3)
w, h = sig.freqz(b, a, worN=4096)

f = w/2.0*fs

然后将IIR滤波器的输出通过一个10倍内插滤波器,以返回到44.1 kHz采样率

或者,减少过滤器顺序:

fs = 44100.0
b2, a2 = sig.iirfilter(1, 2.0/fs * sp.asarray([40, 60]), btype='bandstop')  # 50 hz reject
w2, h2 = sig.freqz(b2, a2, worN=4096)

b3, a3 = sig.iirfilter(1, 2.0/fs * sp.asarray([85, 115]), btype='bandstop')  # 100 hz reject
w3, h3 = sig.freqz(b3, a3, worN=4096)

b = sp.convolve(b2, b3, 'full')
a = sp.convolve(a2, a3, 'full')
w, h = sig.freqz(b, a, worN=4096)
其原始采样率为44.1 kHz


是的,np.卷积。抱歉。请参阅我的问题@fstop_22末尾的编辑,它似乎不适用于
convalve
。感谢您更新的答案。奇怪的是,我们不能用fs=44100来链接它们,因为当一个接一个地应用带阻时,过滤效果非常好。
lfilter(b2,a2,lfilter(b3,a3,x))在数学上做什么?即使在50hz和100hz很接近的情况下,我们不能将其重写为单个lfilter吗?级联响应的零极点图是什么样子的?我不知道(在Python中从未这样做过),但在我的示例中,
y=lfilter(b2,a2,x)
然后
y=lfilter(b3,a3,y)
起作用(并且过滤非常完美),所以我想应该可以找到
a,b
,这样我们就可以一次完成
y=lfilter(b,a,x)
,而不考虑极点零点?如果你把第二个滤波器的零点移离第一个滤波器的零点,比如[850,1000],级联响应是正确的,并且显示两个零点。我怀疑两个滤波器的零极点位置相互干扰。不幸的是,scipy中没有zplane函数来显示零极点的位置。Hm ok@fstop_22,不确定是否完全理解。。。你能修改答案并给出一个在这种情况下的工作示例吗?(50 hz时的IIR滤波器带阻+100 hz时的IIR滤波器带阻)提前感谢您。