Applying filters with lfilter and sosfilt in SciPy
📖 Scenario: You are working with a noisy sensor signal collected from a weather station. The signal contains unwanted high-frequency noise that makes it hard to analyze the true temperature trend.Your task is to apply digital filters to clean the signal so it becomes smoother and easier to interpret.
🎯 Goal: Build a Python program that creates a noisy signal, sets up filter coefficients, applies the filters using lfilter and sosfilt from SciPy, and then prints the filtered results.
📋 What You'll Learn
Create a noisy signal as a list of floats called noisy_signal with exact values
Create filter coefficients as a tuple called b_a with exact values
Create second-order sections filter coefficients as a list called sos with exact values
Use lfilter with b_a and noisy_signal to create filtered_lfilter
Use sosfilt with sos and noisy_signal to create filtered_sosfilt
Print filtered_lfilter and filtered_sosfilt exactly as shown
💡 Why This Matters
🌍 Real World
Filtering noisy sensor data is common in weather stations, medical devices, and audio processing to get clearer signals.
💼 Career
Understanding how to apply digital filters is important for data scientists working with time series, signal processing, and sensor data analysis.
Progress0 / 4 steps
1
Create the noisy signal data
Create a list called noisy_signal with these exact float values: [0.0, 0.9, 0.1, 1.2, 0.3, 1.5, 0.2, 1.7, 0.1, 1.8]
SciPy
Hint
Use square brackets to create a list and separate values with commas.
2
Set up filter coefficients
Create a tuple called b_a with these exact values: ([0.2, 0.2, 0.2], [1.0, -0.5, 0.25]) and a list called sos with this exact nested list: [[0.2, 0.2, 0.2, 1.0, -0.5, 0.25]]
SciPy
Hint
Use parentheses for tuples and square brackets for lists. Match the exact values and structure.
3
Apply filters using lfilter and sosfilt
Import lfilter and sosfilt from scipy.signal. Use lfilter with b_a[0], b_a[1], and noisy_signal to create filtered_lfilter. Use sosfilt with sos and noisy_signal to create filtered_sosfilt.
SciPy
Hint
Use from scipy.signal import lfilter, sosfilt to import. Then call the functions with the correct arguments.
4
Print the filtered results
Print filtered_lfilter and filtered_sosfilt exactly as shown, each on its own line.
SciPy
Hint
Use two print() statements, one for each filtered array.
Practice
(1/5)
1. What is the main purpose of using lfilter in signal processing with SciPy?
easy
A. To generate random noise signals
B. To apply a digital filter using numerator and denominator coefficients
C. To visualize the frequency response of a filter
D. To compute the Fourier transform of a signal
Solution
Step 1: Understand the role of lfilter
lfilter applies a digital filter to a signal using given numerator (b) and denominator (a) coefficients.
Step 2: Compare with other options
Options A, B, and D describe different signal processing tasks unrelated to filtering with coefficients.
Final Answer:
To apply a digital filter using numerator and denominator coefficients -> Option B
Quick Check:
lfilter = apply filter with b, a coefficients [OK]
Hint: Remember: lfilter uses b, a coefficients to filter signals [OK]
Common Mistakes:
Confusing lfilter with Fourier transform functions
Thinking lfilter generates signals instead of filtering
Mixing up lfilter with visualization tools
2. Which of the following is the correct way to import and use lfilter from SciPy to filter a signal array named data with coefficients b and a?
easy
A. from scipy.signal import lfilter; filtered = lfilter(data, b, a)
B. import scipy.signal as signal; filtered = signal.lfilter(data, b, a)
C. from scipy.signal import lfilter; filtered = lfilter(b, a, data)
D. import lfilter from scipy.signal; filtered = lfilter(b, a, data)
Solution
Step 1: Recall the correct import syntax
The correct import is from scipy.signal import lfilter.
Step 2: Check the function call order
lfilter takes arguments in order: numerator coefficients (b), denominator coefficients (a), then the signal (data).
Final Answer:
from scipy.signal import lfilter; filtered = lfilter(b, a, data) -> Option C
Quick Check:
Import and call lfilter(b, a, data) [OK]
Hint: Import lfilter then call with (b, a, data) order [OK]
Common Mistakes:
Swapping the order of arguments in lfilter
Incorrect import syntax causing errors
Passing data as first argument instead of third
3. Given the code below, what will be the output of filtered_signal?
from scipy.signal import lfilter
b = [0.2, 0.2, 0.2, 0.2, 0.2]
a = [1]
data = [1, 2, 3, 4, 5]
filtered_signal = lfilter(b, a, data)
print(list(filtered_signal))
medium
A. [0.2, 0.6, 1.2, 2.0, 3.0]
B. [1, 2, 3, 4, 5]
C. [0.2, 0.2, 0.2, 0.2, 0.2]
D. [0, 0, 0, 0, 0]
Solution
Step 1: Understand the filter coefficients
The numerator coefficients b average the last 5 samples equally (each 0.2), denominator a is 1 (no feedback).
Hint: Sum weighted inputs by b coefficients for each output [OK]
Common Mistakes:
Ignoring the filter coefficients and outputting original data
Confusing denominator coefficients effect
Calculating only single sample instead of cumulative
4. What is wrong with the following code snippet that attempts to filter a signal using sosfilt?
from scipy.signal import sosfilt
sos = [[0.2929, 0.5858, 0.2929, 1, -0.0000, 0.1716]]
data = [1, 2, 3, 4, 5]
filtered = sosfilt(sos, data)
print(filtered)
medium
A. The sos array should have denominator coefficients in positions 3, 4, 5, but here the second denominator coefficient is zero, which is invalid
B. The denominator coefficients in sos must be normalized; here they are not
C. The sos array should be a 2D array with float values, but the given sos is a list of lists which is invalid
D. The sos array must have shape (n_sections, 6), but here it has shape (1, 6) which is correct
Solution
Step 1: Check the sos array format
The sos array must be a 2D array with each row having 6 coefficients: [b0, b1, b2, a0, a1, a2].
Step 2: Validate denominator coefficients
Denominator coefficients (a0, a1, a2) must be valid. Here, a0=1 (correct), a1=-0.0000 (effectively zero), a2=0.1716. Having a1 near zero is unusual and can cause instability or errors.
Final Answer:
The sos array should have denominator coefficients in positions 3, 4, 5, but here the second denominator coefficient is zero, which is invalid -> Option A
Quick Check:
sos denominator coefficients must be valid and non-zero [OK]
Hint: Check sos denominator coefficients are valid and non-zero [OK]
Confusing numerator and denominator positions in sos
5. You want to apply a stable Butterworth low-pass filter of order 4 with cutoff frequency 0.3 (normalized) to a noisy signal data. Which approach is best to ensure numerical stability and why?
A) Use lfilter with numerator and denominator coefficients from butter.
B) Use sosfilt with second-order sections from butter.
C) Use lfilter with only numerator coefficients.
D) Use sosfilt with random coefficients.
hard
A. Use lfilter with numerator and denominator coefficients from butter
B. Use sosfilt with random coefficients
C. Use lfilter with only numerator coefficients ignoring denominator
D. Use sosfilt with second-order sections from butter for better stability
Solution
Step 1: Understand filter stability issues
High order filters can be unstable when applied directly with numerator and denominator coefficients due to numerical errors.
Step 2: Recognize sosfilt advantage
Using second-order sections (sos) breaks the filter into smaller stable parts, improving numerical stability.
Step 3: Evaluate options
Use sosfilt with second-order sections from butter for better stability (recommended stable method). Options C and D are incorrect or nonsensical.
Final Answer:
Use sosfilt with second-order sections from butter for better stability -> Option D
Quick Check:
Use sosfilt with sos for stable filtering [OK]
Hint: Use sosfilt with butter sos for stable high-order filters [OK]
Common Mistakes:
Using lfilter directly for high order filters causing instability
Ignoring denominator coefficients in filtering
Using random coefficients causing wrong results
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.