bundles / scipy 2.0.0.dev0+git20260907.41eeb59 / scipy / signal / _signaltools / filtfilt
function
scipy.signal._signaltools:filtfilt
source: build-install/usr/lib/python3.14/site-packages/scipy/signal/_signaltools.py:4893
Signature
def filtfilt(b, a, x, axis = -1, padtype = odd, padlen = None, method = pad, irlen = None)Summary
Apply a digital filter forward and backward to a signal.
Extended Summary
This function applies a linear digital filter twice, once forward and once backwards. The combined filter has zero phase and a filter order twice that of the original.
The function provides options for handling the edges of the signal.
The function sosfiltfilt (and filter design using output='sos') should be preferred over filtfilt for most filtering tasks, as second-order sections have fewer numerical problems.
Parameters
b: (N,) array_likeThe numerator coefficient vector of the filter.
a: (N,) array_likeThe denominator coefficient vector of the filter. If
a[0]is not 1, then bothaandbare normalized bya[0].x: array_likeThe array of data to be filtered.
axis: int, optionalThe axis of
xto which the filter is applied. Default is -1.padtype: str or None, optionalMust be 'odd', 'even', 'constant', or None. This determines the type of extension to use for the padded signal to which the filter is applied. If
padtypeis None, no padding is used. The default is 'odd'.padlen: int or None, optionalThe number of elements by which to extend
xat both ends ofaxisbefore applying the filter. This value must be less thanx.shape[axis] - 1.padlen=0implies no padding. The default value is3 * max(len(a), len(b)).method: str, optionalDetermines the method for handling the edges of the signal, either "pad" or "gust". When
methodis "pad", the signal is padded; the type of padding is determined bypadtypeandpadlen, andirlenis ignored. Whenmethodis "gust", Gustafsson's method is used, andpadtypeandpadlenare ignored.irlen: int or None, optionalWhen
methodis "gust",irlenspecifies the length of the impulse response of the filter. Ifirlenis None, no part of the impulse response is ignored. For a long signal, specifyingirlencan significantly improve the performance of the filter.
Returns
y: ndarrayThe filtered output with the same shape as
x.
Notes
When method is "pad", the function pads the data along the given axis in one of three ways: odd, even or constant. The odd and even extensions have the corresponding symmetry about the end point of the data. The constant extension extends the data with the values at the end points. On both the forward and backward passes, the initial condition of the filter is found by using lfilter_zi and scaling it by the end point of the extended data.
When method is "gust", Gustafsson's method [1] is used. Initial conditions are chosen for the forward and backward passes so that the forward-backward filter gives the same result as the backward-forward filter.
The option to use Gustaffson's method was added in scipy version 0.16.0.
Examples
The examples will use several functions from `scipy.signal`.import numpy as np from scipy import signal import matplotlib.pyplot as plt✓
t = np.linspace(0, 1.0, 2001) xlow = np.sin(2 * np.pi * 5 * t) xhigh = np.sin(2 * np.pi * 250 * t) x = xlow + xhigh✓
b, a = signal.butter(8, 0.125) y = signal.filtfilt(b, a, x, padlen=150)✓
np.abs(y - xlow).max()
✗np.float64(9.1086292874909e-06)We get a fairly clean result for this artificial example because the odd extension is exact, and with the moderately long padding, the filter's transients have dissipated by the time the actual data is reached. In general, transient effects at the edges are unavoidable. The following example demonstrates the option ``method="gust"``. First, create a filter.
b, a = signal.ellip(4, 0.01, 120, 0.125) # Filter to be applied.
✓rng = np.random.default_rng() n = 60 sig = rng.standard_normal(n)**3 + 3*rng.standard_normal(n).cumsum()✓
fgust = signal.filtfilt(b, a, sig, method="gust") fpad = signal.filtfilt(b, a, sig, padlen=50)✓
plt.plot(sig, 'k-', label='input') plt.plot(fgust, 'b-', linewidth=4, label='gust') plt.plot(fpad, 'c-', linewidth=1.5, label='pad') plt.legend(loc='best')✗
<matplotlib.legend.Legend object at 0x7f3f682682f0>
plt.show()
✓
z, p, k = signal.tf2zpk(b, a) eps = 1e-9 r = np.max(np.abs(p)) approx_impulse_len = int(np.ceil(np.log(eps) / np.log(r))) approx_impulse_len✓
137Apply the filter to a longer signal, with and without the `irlen` argument. The difference between `y1` and `y2` is small. For long signals, using `irlen` gives a significant performance improvement.
x = rng.standard_normal(4000) y1 = signal.filtfilt(b, a, x, method='gust') y2 = signal.filtfilt(b, a, x, method='gust', irlen=approx_impulse_len)✓
print(np.max(np.abs(y1 - y2)))
✗1.7041967836917138e-10
See also
Aliases
scipy.signal.filtfilt