SciPy Signal Processing

The scipy.signal module offers signal processing tools such as filtering, convolution, and spectral analysis. Whether you’re working with audio, images, or sensor data, these routines help denoise, transform, and analyze signals effectively.

Key Topics

Filters

SciPy provides methods to design and apply filters (e.g., low-pass, high-pass) in both the time domain and frequency domain. Digital filter design (IIR, FIR) can be done with functions like signal.butter and signal.firwin.

Example: Low-Pass Filter

import numpy as np
from scipy import signal
import matplotlib.pyplot as plt

# Generate a noisy signal
fs = 1000  # sampling frequency
t = np.linspace(0, 1, fs, endpoint=False)
sig = np.sin(2*np.pi*50*t) + 0.5 * np.random.randn(t.size)

# Design a low-pass Butterworth filter
b, a = signal.butter(4, 100, btype='low', fs=fs)
filtered = signal.filtfilt(b, a, sig)

plt.plot(t, sig, label='Noisy Signal')
plt.plot(t, filtered, label='Filtered Signal')
plt.legend()
plt.show()

Output

A plot comparing the original noisy signal and the filtered signal.

Explanation: We generate a sine wave with added noise, then apply a low-pass Butterworth filter to remove high-frequency noise. filtfilt applies the filter forward and backward to reduce phase distortion.

Example: High-Pass Filter

import numpy as np
from scipy import signal
import matplotlib.pyplot as plt

# Generate a signal with low-frequency noise
fs = 1000  # sampling frequency
t = np.linspace(0, 1, fs, endpoint=False)
sig = np.sin(2*np.pi*5*t) + np.sin(2*np.pi*50*t)

# Design a high-pass Butterworth filter
b, a = signal.butter(4, 20, btype='high', fs=fs)
filtered = signal.filtfilt(b, a, sig)

plt.plot(t, sig, label='Original Signal')
plt.plot(t, filtered, label='Filtered Signal')
plt.legend()
plt.show()

Output

A plot comparing the original signal with low-frequency noise and the filtered signal.

Explanation: We generate a signal with low-frequency noise and apply a high-pass Butterworth filter to remove the low-frequency component. The filtered signal retains the high-frequency component.

Convolution

scipy.signal.convolve and signal.correlate help perform convolution and correlation operations for tasks like smoothing, feature extraction, and signal matching.

Example: Signal Smoothing

import numpy as np
from scipy import signal
import matplotlib.pyplot as plt

# Generate a noisy signal
np.random.seed(0)
sig = np.cumsum(np.random.randn(1000))

# Create a smoothing window
window = signal.windows.hann(50)
smoothed = signal.convolve(sig, window, mode='same') / sum(window)

plt.plot(sig, label='Noisy Signal')
plt.plot(smoothed, label='Smoothed Signal')
plt.legend()
plt.show()

Output

A plot comparing the original noisy signal and the smoothed signal.

Explanation: We generate a noisy cumulative sum signal and apply a Hann window for smoothing using convolution. The smoothed signal shows reduced noise.

Spectral Analysis

Use functions like signal.periodogram or signal.welch to estimate power spectral densities, crucial in identifying frequency components of signals.

Example: Power Spectral Density

import numpy as np
from scipy import signal
import matplotlib.pyplot as plt

# Generate a signal with two frequency components
fs = 1000  # sampling frequency
t = np.linspace(0, 1, fs, endpoint=False)
sig = np.sin(2*np.pi*50*t) + np.sin(2*np.pi*120*t)

# Compute power spectral density using Welch's method
frequencies, psd = signal.welch(sig, fs, nperseg=256)

plt.semilogy(frequencies, psd)
plt.title('Power Spectral Density')
plt.xlabel('Frequency (Hz)')
plt.ylabel('Power/Frequency (dB/Hz)')
plt.show()

Output

A plot showing the power spectral density with peaks at 50 Hz and 120 Hz.

Explanation: We generate a signal with two frequency components and use Welch's method to estimate the power spectral density. The plot shows peaks at the frequencies of the components.

Resampling

Resampling is the process of changing the sampling rate of a signal. Use signal.resample for Fourier method resampling or signal.resample_poly for polyphase filtering.

Example: Resampling a Signal

import numpy as np
from scipy import signal
import matplotlib.pyplot as plt

# Generate a signal
fs = 1000  # original sampling frequency
t = np.linspace(0, 1, fs, endpoint=False)
sig = np.sin(2*np.pi*50*t)

# Resample the signal to a lower sampling rate
new_fs = 200  # new sampling frequency
resampled_sig = signal.resample(sig, int(len(sig) * new_fs / fs))
new_t = np.linspace(0, 1, len(resampled_sig), endpoint=False)

plt.plot(t, sig, label='Original Signal')
plt.plot(new_t, resampled_sig, label='Resampled Signal')
plt.legend()
plt.show()

Output

A plot comparing the original signal and the resampled signal.

Explanation: We generate a sine wave and resample it to a lower sampling rate using Fourier method resampling. The resampled signal retains the original frequency content but with fewer samples.

Key Takeaways

  • Filtering: Design and apply various filters for noise reduction.
  • Convolution & Correlation: Integral for signal shaping and detection tasks.
  • Spectral Methods: Gain insights into frequency components of your data.
  • Resampling: Change the sampling rate of signals efficiently.
  • Integration: Works seamlessly with NumPy arrays, Matplotlib for plotting.