I would like to apply a 2nd order low-pass Butterworth filter on my data, and then use cubic spline interpolation for resampling at every 1 meter in Python.
I tried to prevent havin no-finite values but I still receive the following ValueError:
cs_v = CubicSpline(distance, filtered_v)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ raise ValueError("
xmust contain only finite values.") ValueError:
x` must contain only finite values.
Here are the relavant parts of my code:
<code>import numpy as np
import pandas as pd
from scipy.signal import butter, filtfilt
from scipy.interpolate import CubicSpline, interp1d
import matplotlib.pyplot as plt
import plotly.graph_objects as go
# Butterworth filter
def butterworth_filter(data, cutoff, fs, order=2):
nyquist = 0.5 * fs
normal_cutoff = cutoff / nyquist
b, a = butter(order, normal_cutoff, btype='low', analog=False)
y = filtfilt(b, a, data)
return y
# ensuring data arrays are finite
def ensure_finite(data):
nans = np.isnan(data) | np.isinf(data)
if np.any(nans):
interp_func = interp1d(np.arange(len(data))[~nans], data[~nans], kind='linear', fill_value="extrapolate")
data[nans] = interp_func(np.arange(len(data))[nans])
return data
def handle_infinite(data, t):
nans = np.isnan(data) | np.isinf(data)
if np.any(nans):
valid_mask = ~nans
if valid_mask.sum() < 2:
raise ValueError("No valid data.")
interp_func = interp1d(t[valid_mask], data[valid_mask], kind='linear', fill_value="extrapolate")
data[nans] = interp_func(t[nans])
return data
# ...
data = pd.read_excel(r"xy")
t = data['Time'].values
x = data['X'].values
y = data['Y'].values
v = data['speed'].values
z = data['altitude'].values
a = data['acceleration'].values
distance = data['distance'].values
# Set initial NaN value in distance to 0
if np.isnan(distance[0]):
distance[0] = 0
# Ensuring distance array is increasing
sorted_indices = np.argsort(distance)
distance = distance[sorted_indices]
x = x[sorted_indices]
y = y[sorted_indices]
v = v[sorted_indices]
z = z[sorted_indices]
a = a[sorted_indices]
# Ensuring data arrays are finite
v = ensure_finite(v)
a = ensure_finite(a)
z = ensure_finite(z)
x = ensure_finite(x)
y = ensure_finite(y)
# Butterworth filter
fs = 1 / (t[1] - t[0]) # sampling frequency
cutoff = 0.3 # frequency
filtered_v = butterworth_filter(v, cutoff, fs)
filtered_a = butterworth_filter(a, cutoff, fs)
filtered_z = butterworth_filter(z, cutoff, fs)
filtered_v = handle_infinite(filtered_v, t)
filtered_a = handle_infinite(filtered_a, t)
filtered_z = handle_infinite(filtered_z, t)
print(filtered_v)
print(filtered_z)
# Resampling
distance_new = np.arange(0, distance[0], 1) # at every 1 meter
cs_v = CubicSpline(distance, filtered_v)
cs_a = CubicSpline(distance, filtered_a)
cs_z = CubicSpline(distance, filtered_z)
cs_x = CubicSpline(distance, x)
cs_y = CubicSpline(distance, y)
v_cubic = cs_v(distance_new)
a_cubic = cs_a(distance_new)
z_cubic = cs_z(distance_new)
x_cubic = cs_x(distance_new)
y_cubic = cs_y(distance_new)
</code>
<code>import numpy as np
import pandas as pd
from scipy.signal import butter, filtfilt
from scipy.interpolate import CubicSpline, interp1d
import matplotlib.pyplot as plt
import plotly.graph_objects as go
# Butterworth filter
def butterworth_filter(data, cutoff, fs, order=2):
nyquist = 0.5 * fs
normal_cutoff = cutoff / nyquist
b, a = butter(order, normal_cutoff, btype='low', analog=False)
y = filtfilt(b, a, data)
return y
# ensuring data arrays are finite
def ensure_finite(data):
nans = np.isnan(data) | np.isinf(data)
if np.any(nans):
interp_func = interp1d(np.arange(len(data))[~nans], data[~nans], kind='linear', fill_value="extrapolate")
data[nans] = interp_func(np.arange(len(data))[nans])
return data
def handle_infinite(data, t):
nans = np.isnan(data) | np.isinf(data)
if np.any(nans):
valid_mask = ~nans
if valid_mask.sum() < 2:
raise ValueError("No valid data.")
interp_func = interp1d(t[valid_mask], data[valid_mask], kind='linear', fill_value="extrapolate")
data[nans] = interp_func(t[nans])
return data
# ...
data = pd.read_excel(r"xy")
t = data['Time'].values
x = data['X'].values
y = data['Y'].values
v = data['speed'].values
z = data['altitude'].values
a = data['acceleration'].values
distance = data['distance'].values
# Set initial NaN value in distance to 0
if np.isnan(distance[0]):
distance[0] = 0
# Ensuring distance array is increasing
sorted_indices = np.argsort(distance)
distance = distance[sorted_indices]
x = x[sorted_indices]
y = y[sorted_indices]
v = v[sorted_indices]
z = z[sorted_indices]
a = a[sorted_indices]
# Ensuring data arrays are finite
v = ensure_finite(v)
a = ensure_finite(a)
z = ensure_finite(z)
x = ensure_finite(x)
y = ensure_finite(y)
# Butterworth filter
fs = 1 / (t[1] - t[0]) # sampling frequency
cutoff = 0.3 # frequency
filtered_v = butterworth_filter(v, cutoff, fs)
filtered_a = butterworth_filter(a, cutoff, fs)
filtered_z = butterworth_filter(z, cutoff, fs)
filtered_v = handle_infinite(filtered_v, t)
filtered_a = handle_infinite(filtered_a, t)
filtered_z = handle_infinite(filtered_z, t)
print(filtered_v)
print(filtered_z)
# Resampling
distance_new = np.arange(0, distance[0], 1) # at every 1 meter
cs_v = CubicSpline(distance, filtered_v)
cs_a = CubicSpline(distance, filtered_a)
cs_z = CubicSpline(distance, filtered_z)
cs_x = CubicSpline(distance, x)
cs_y = CubicSpline(distance, y)
v_cubic = cs_v(distance_new)
a_cubic = cs_a(distance_new)
z_cubic = cs_z(distance_new)
x_cubic = cs_x(distance_new)
y_cubic = cs_y(distance_new)
</code>
import numpy as np
import pandas as pd
from scipy.signal import butter, filtfilt
from scipy.interpolate import CubicSpline, interp1d
import matplotlib.pyplot as plt
import plotly.graph_objects as go
# Butterworth filter
def butterworth_filter(data, cutoff, fs, order=2):
nyquist = 0.5 * fs
normal_cutoff = cutoff / nyquist
b, a = butter(order, normal_cutoff, btype='low', analog=False)
y = filtfilt(b, a, data)
return y
# ensuring data arrays are finite
def ensure_finite(data):
nans = np.isnan(data) | np.isinf(data)
if np.any(nans):
interp_func = interp1d(np.arange(len(data))[~nans], data[~nans], kind='linear', fill_value="extrapolate")
data[nans] = interp_func(np.arange(len(data))[nans])
return data
def handle_infinite(data, t):
nans = np.isnan(data) | np.isinf(data)
if np.any(nans):
valid_mask = ~nans
if valid_mask.sum() < 2:
raise ValueError("No valid data.")
interp_func = interp1d(t[valid_mask], data[valid_mask], kind='linear', fill_value="extrapolate")
data[nans] = interp_func(t[nans])
return data
# ...
data = pd.read_excel(r"xy")
t = data['Time'].values
x = data['X'].values
y = data['Y'].values
v = data['speed'].values
z = data['altitude'].values
a = data['acceleration'].values
distance = data['distance'].values
# Set initial NaN value in distance to 0
if np.isnan(distance[0]):
distance[0] = 0
# Ensuring distance array is increasing
sorted_indices = np.argsort(distance)
distance = distance[sorted_indices]
x = x[sorted_indices]
y = y[sorted_indices]
v = v[sorted_indices]
z = z[sorted_indices]
a = a[sorted_indices]
# Ensuring data arrays are finite
v = ensure_finite(v)
a = ensure_finite(a)
z = ensure_finite(z)
x = ensure_finite(x)
y = ensure_finite(y)
# Butterworth filter
fs = 1 / (t[1] - t[0]) # sampling frequency
cutoff = 0.3 # frequency
filtered_v = butterworth_filter(v, cutoff, fs)
filtered_a = butterworth_filter(a, cutoff, fs)
filtered_z = butterworth_filter(z, cutoff, fs)
filtered_v = handle_infinite(filtered_v, t)
filtered_a = handle_infinite(filtered_a, t)
filtered_z = handle_infinite(filtered_z, t)
print(filtered_v)
print(filtered_z)
# Resampling
distance_new = np.arange(0, distance[0], 1) # at every 1 meter
cs_v = CubicSpline(distance, filtered_v)
cs_a = CubicSpline(distance, filtered_a)
cs_z = CubicSpline(distance, filtered_z)
cs_x = CubicSpline(distance, x)
cs_y = CubicSpline(distance, y)
v_cubic = cs_v(distance_new)
a_cubic = cs_a(distance_new)
z_cubic = cs_z(distance_new)
x_cubic = cs_x(distance_new)
y_cubic = cs_y(distance_new)
Thanks for your help!