Skip to content

Instantly share code, notes, and snippets.

@cboulay
Last active January 10, 2018 15:46
Show Gist options
  • Save cboulay/18c038a8de3924a68c1fd56e1c6187a1 to your computer and use it in GitHub Desktop.
Save cboulay/18c038a8de3924a68c1fd56e1c6187a1 to your computer and use it in GitHub Desktop.
Example showing processing time difference for filtering numpy signals along different axes.
import numpy as np
from scipy import signal
fs = 30000 # Hz
n_chans = 100
sig_dur = 300.0 # seconds
lp_cutoff = 250 # Hz
lp_order = 8
sig_freq_low = 14 # Frequency of sine wave in signal
sig_amp_low = 10.0 # Amplitude of sine wave in signal
sig_freq_high = 500
sig_amp_high = 5.0
t = np.linspace(0, sig_dur, fs)
sig = sig_amp_low * np.sin(2 * np.pi * sig_freq_low * t) + sig_amp_high * np.sin(2 * np.pi * sig_freq_high * t)
# Create matrices. Use broadcast addition.
# Note that we cannot simply use the transpose because .T does not change the memory layout.
sig_R = sig[:, None] + np.zeros((len(t), n_chans)) # time in Rows
sig_C = sig[None, :] + np.zeros((n_chans, len(t))) # time in Columns
print("Is c_contiguous? sig_R: ", sig_R.shape, sig_R.flags.c_contiguous,
"; sig_C: ", sig_C.shape, sig_C.flags.c_contiguous)
# Create the filter
sos = signal.butter(lp_order, lp_cutoff/(fs/2), output='sos')
# Time signal filtering
%timeit signal.sosfiltfilt(sos, sig_R, axis=0)
# 485 ms ± 33.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit signal.sosfiltfilt(sos, sig_C, axis=-1)
# 235 ms ± 12.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
# Optional, plot to verify the filter operation works as intended.
import matplotlib.pyplot as plt
plt.figure()
plt.plot(t, sig)
# plot filtered signals with offsets so you can actually see them.
plt.plot(t, signal.sosfiltfilt(sos, sig_R, axis=0)[:, 0] - 1) # orange
plt.plot(t, signal.sosfiltfilt(sos, sig_C, axis=-1)[0, :] + 1) # green
plt.show()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment