См. https://dsp.stackexchange.com/questions/38675/how-to-plot-magnitude-and-phase-response-of-2-cascaded-filters-in-matlab
Вы можете свертывать числители и знаменатели отдельно
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 кГц.
Вот результаты с частотой дискретизации, уменьшенной до 4410 Гц.
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
Затем пропустите выход БИХ-фильтра через 10-кратный интерполяционный фильтр, чтобы вернуться к частоте выборки 44,1 кГц.
ИЛИ, уменьшите порядок фильтра:
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 кГц