You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中Cubic Spline插值报错:`x`必须仅含有限值,如何解决?

问题

我想在Python中对数据应用二阶低通Butterworth滤波器,之后用三次样条插值按每1米间隔重采样。已经尝试处理非有限值,但仍收到如下ValueError:

cs_v = CubicSpline(distance, filtered_v)     
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
raise ValueError("`x` must contain only finite values.")
ValueError: `x` must contain only finite values.

相关代码

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滤波器
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

# 确保数据数组为有限值
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


# 将distance的初始NaN值设为0
if np.isnan(distance[0]):
    distance[0] = 0


# 确保distance数组递增
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]

# 确保数据数组为有限值 
v = ensure_finite(v)
a = ensure_finite(a)
z = ensure_finite(z)
x = ensure_finite(x)
y = ensure_finite(y)

# Butterworth滤波
fs = 1 / (t[1] - t[0])  # 采样频率
cutoff = 0.3  # 截止频率

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)


# 重采样
distance_new = np.arange(0, distance[0], 1)  # 每1米间隔


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)

解决方案

错误核心是distance数组中仍存在非有限值(NaN/Inf),你仅处理了其他数据数组的异常值,未对distance做完整处理,同时代码还存在两处逻辑疏漏,修复步骤如下:

1. 完整处理distance的非有限值

在排序后,对distance应用你已有的异常值处理函数,同步修正时间数组t的对应关系:

# 确保distance数组递增
sorted_indices = np.argsort(distance)
distance = distance[sorted_indices]
t = t[sorted_indices]  # 必须同步排序t,否则后续插值对应关系错乱
x = x[sorted_indices]
y = y[sorted_indices]
v = v[sorted_indices]
z = z[sorted_indices]
a = a[sorted_indices]

# 处理distance的非有限值
distance = handle_infinite(distance, t)

2. 修正重采样范围逻辑

当前distance_new = np.arange(0, distance[0], 1)会生成空数组或仅覆盖极小范围,应改为覆盖整个distance的取值区间:

distance_new = np.arange(np.min(distance), np.max(distance)+1, 1)

3. 添加有效性检查(可选但推荐)

在创建三次样条前,添加断言确保distance无异常值:

assert np.all(np.isfinite(distance)), "distance数组存在非有限值"

4. 处理distance重复值(可选)

如果distance存在重复值,CubicSpline也会报错,可添加去重逻辑:

# 去重并保留首次出现的索引
unique_indices = np.unique(distance, return_index=True)[1]
distance = distance[unique_indices]
t = t[unique_indices]
x = x[unique_indices]
y = y[unique_indices]
v = v[unique_indices]
z = z[unique_indices]
a = a[unique_indices]

内容的提问来源于stack exchange,提问作者Márton Horváth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 12:13:14