How to Implement Decimation in Python for Signal Processing
In Python, you can implement
decimation using the scipy.signal.decimate function, which reduces the sampling rate of a signal by an integer factor while applying an anti-aliasing filter. This method simplifies downsampling by combining filtering and downsampling in one step.Syntax
The scipy.signal.decimate function syntax is:
scipy.signal.decimate(x, q, n=None, ftype='iir', zero_phase=True)
Where:
x: input signal arrayq: integer factor to reduce the sampling rate byn: order of the filter (optional)ftype: filter type, either 'iir' (default) or 'fir'zero_phase: if True, applies zero-phase filtering to avoid phase shift
python
from scipy.signal import decimate decimated_signal = decimate(x, q, n=None, ftype='iir', zero_phase=True)
Example
This example shows how to decimate a noisy sine wave signal by a factor of 4 using scipy.signal.decimate. It plots the original and decimated signals for comparison.
python
import numpy as np import matplotlib.pyplot as plt from scipy.signal import decimate # Create a sample signal: 5 Hz sine wave sampled at 100 Hz fs = 100 # original sampling frequency t = np.linspace(0, 1, fs, endpoint=False) signal = np.sin(2 * np.pi * 5 * t) + 0.1 * np.random.randn(len(t)) # Decimate by factor of 4 q = 4 signal_decimated = decimate(signal, q) # New time vector after decimation t_decimated = np.linspace(0, 1, len(signal_decimated), endpoint=False) # Plot original and decimated signals plt.figure(figsize=(10, 4)) plt.plot(t, signal, label='Original Signal') plt.plot(t_decimated, signal_decimated, 'o-', label='Decimated Signal (factor 4)') plt.xlabel('Time [seconds]') plt.ylabel('Amplitude') plt.legend() plt.title('Signal Decimation Example') plt.tight_layout() plt.show()
Output
A plot showing the original noisy sine wave sampled at 100 Hz and the decimated signal sampled at 25 Hz with fewer points but similar shape.
Common Pitfalls
Common mistakes when implementing decimation include:
- Not applying an anti-aliasing filter before downsampling, which causes distortion.
- Using a non-integer decimation factor, which
scipy.signal.decimatedoes not support. - Ignoring phase distortion; setting
zero_phase=Truehelps avoid this. - Choosing too low filter order
n, leading to poor filtering.
python
import numpy as np from scipy.signal import decimate # Wrong: Downsampling without filtering (manual slicing) signal = np.sin(2 * np.pi * 5 * np.linspace(0, 1, 100)) downsampled_wrong = signal[::4] # No filtering, causes aliasing # Right: Using decimate with filtering downsampled_right = decimate(signal, 4, zero_phase=True)
Quick Reference
Tips for decimation in Python:
- Use
scipy.signal.decimatefor combined filtering and downsampling. - Choose an integer decimation factor
q. - Set
zero_phase=Trueto avoid phase shifts. - Increase filter order
nif signal distortion occurs. - For very large downsampling, consider multi-stage decimation.
Key Takeaways
Use scipy.signal.decimate to downsample signals with built-in anti-aliasing filtering.
Always use an integer decimation factor and avoid manual slicing without filtering.
Set zero_phase=True to prevent phase distortion in the output signal.
Adjust filter order n if the decimated signal shows distortion or aliasing.
Visualize signals before and after decimation to verify quality.