How to Implement FIR Filter in Python: Simple Guide
To implement a
FIR filter in Python, you can use the scipy.signal.lfilter function with filter coefficients created by scipy.signal.firwin. This applies the filter to your data by convolving it with the FIR coefficients.Syntax
The basic syntax to apply a FIR filter in Python is:
firwin(numtaps, cutoff, window='hamming', pass_zero='lowpass'): Creates FIR filter coefficients.lfilter(b, a, x): Applies the filter to dataxusing coefficientsband denominatora.
For FIR filters, a is usually 1 because FIR filters have only zeros (no poles).
python
from scipy.signal import firwin, lfilter # Create FIR filter coefficients numtaps = 51 # Number of filter taps (coefficients) cutoff = 0.3 # Normalized cutoff frequency (0 to 1, where 1 is Nyquist frequency) coefficients = firwin(numtaps, cutoff, window='hamming') # Apply FIR filter to data # b = coefficients, a = 1 for FIR filter filtered_signal = lfilter(coefficients, 1, [1, 2, 3, 4, 5])
Example
This example shows how to create a low-pass FIR filter and apply it to a noisy sine wave signal to smooth it.
python
import numpy as np import matplotlib.pyplot as plt from scipy.signal import firwin, lfilter # Generate sample data: noisy sine wave fs = 500 # Sampling frequency in Hz T = 1.0 # seconds t = np.linspace(0, T, int(fs*T), endpoint=False) signal = np.sin(2 * np.pi * 5 * t) + 0.5 * np.random.randn(len(t)) # Design FIR filter numtaps = 101 cutoff = 0.1 # Normalized cutoff frequency (0 to 1, where 1 is Nyquist frequency) coefficients = firwin(numtaps, cutoff, window='hamming') # Apply FIR filter filtered_signal = lfilter(coefficients, 1, signal) # Plot original and filtered signals plt.figure(figsize=(10, 6)) plt.plot(t, signal, label='Noisy Signal') plt.plot(t, filtered_signal, label='Filtered Signal', linewidth=2) plt.xlabel('Time [seconds]') plt.ylabel('Amplitude') plt.title('FIR Filter Applied to Noisy Signal') plt.legend() plt.grid(True) plt.show()
Output
A plot showing the noisy sine wave and the smoother filtered signal over time.
Common Pitfalls
- Wrong cutoff frequency: The cutoff must be normalized between 0 and 1, where 1 is the Nyquist frequency (half the sampling rate).
- Filter delay: FIR filters introduce delay equal to half the filter length; this can shift your signal in time.
- Using
lfiltervsfiltfilt:lfilterapplies filter once causing phase delay;filtfiltapplies forward and backward to remove delay but doubles computation. - Filter length too short: Too few taps can cause poor filtering; too many taps increase computation.
python
from scipy.signal import filtfilt # Using lfilter (causes delay) filtered_lfilter = lfilter(coefficients, 1, signal) # Using filtfilt (zero phase delay) filtered_filtfilt = filtfilt(coefficients, 1, signal)
Quick Reference
Here is a quick summary of key FIR filter steps in Python:
| Step | Function | Description |
|---|---|---|
| Design filter | firwin(numtaps, cutoff) | Create FIR coefficients |
| Apply filter | lfilter(b, 1, x) | Filter signal x with coefficients b |
| Remove delay | filtfilt(b, 1, x) | Zero-phase filtering (optional) |
| Step | Function | Description |
|---|---|---|
| Design filter | firwin(numtaps, cutoff) | Create FIR coefficients |
| Apply filter | lfilter(b, 1, x) | Filter signal x with coefficients b |
| Remove delay | filtfilt(b, 1, x) | Zero-phase filtering (optional) |
Key Takeaways
Use scipy.signal.firwin to create FIR filter coefficients with desired cutoff.
Apply the FIR filter to data using scipy.signal.lfilter with denominator 1.
Normalize cutoff frequency between 0 and 1, where 1 is Nyquist frequency.
FIR filters introduce delay; use filtfilt to remove phase delay if needed.
Choose filter length (numtaps) carefully for balance between smoothness and performance.