为什么 scipy.filtfilt 和 scipy.lfilter 之间的幅度响应存在差异?

Why is there a difference in magnitude response between scipy.filtfilt and scipy.lfilter?

我试图使用 python 的 scipy 模块过滤信号,我想看看 lfilter 或 filtfilt 哪个更好。 我试着比较它们,然后从我的 mwe

中得到了下面的图
import numpy as np
import scipy.signal as sp
import matplotlib.pyplot as plt

frequency = 100.             #cycles/second
samplingFrequency = 2500.         #samples/second
amplitude = 16384   
signalDuration = 2.3
cycles = frequency*signalDuration

time = np.linspace(0, 2*np.pi*cycles, signalDuration*samplingFrequency)
freq = np.fft.fftfreq(time.shape[-1])
inputSine = amplitude*np.sin(time)
#Create IIR Filter
b, a = sp.iirfilter(1, 0.3, btype = 'lowpass')

#Apply filter to input
filteredSignal = sp.filtfilt(b, a, inputSine)
filteredSignalInFrequency = np.fft.fft(filteredSignal)
filteredSignal2 = sp.lfilter(b, a, inputSine)
filteredSignal2InFrequency = np.fft.fft(filteredSignal2)

plt.close('all')
plt.figure(1)
plt.title('Sine filtered with filtfilt')
plt.plot(freq, abs(filteredSignalInFrequency))
plt.subplot(122)
plt.title('Sine filtered with lfilter')
plt.plot(freq, abs(filteredSignal2InFrequency))

print max(abs(filteredSignalInFrequency))
print max(abs(filteredSignal2InFrequency))
plt.show()

有人可以解释为什么幅度响应有差异吗?

非常感谢您的帮助。

查看您的图表表明,与 4.56x107 用于用 lfilter 过滤的信号。换句话说,用 filtfilt 过滤的信号的峰值幅度是用

过滤时的 0.97

现在我们应该注意 scipy.signal.filtfilt applies the filter twice, whereas scipy.signal.lfilter 只应用一次。结果,输入信号衰减了两倍。为了确认这一点,我们可以查看您使用的 Butterworth 滤波器(通过 iirfilter 获得)在输入音调的归一化频率 100/2500 = 0.04:

附近的频率响应

这确实表明应用此滤波器确实会导致频率为 0.04 时的衰减约为 0.97。