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

Scipy三次插值返回NaN问题求助

三次样条插值返回NaN的问题排查与解决

问题复现

用户执行三次样条插值时返回NaN,但线性插值结果正常,相关代码与参数如下:

import numpy
import scipy

s = 2.8353126768180923

speed = numpy.array(
     [ 1.02119705,  2.04239409,  3.06359114,  4.08478819,  5.10598524,
       6.12718228,  7.14837933,  8.16957638,  9.19077343, 10.25490073,
       11.3278126 , 12.4095641 , 13.50021059, 14.59980773, 15.64265114,
       16.68549455, 17.72833796, 18.77118137, 19.81402478, 20.85686819,
       21.8997116 , 22.94255501, 23.98539842, 25.        , 25.        ])

power = numpy.array(
     [ 0. ,    3.6,   29.9,   98.2,  208.3,  384.3,  637. ,  975.8,
       1403.6, 1817.8, 2088.7, 2237. , 2300. , 2350. , 2350. , 2350. ,
       2350. , 2350. , 2350. , 2350. , 2350. , 2350. , 2350. , 2350. ,
       2350. ])

插值执行代码:

cubic = scipy.interpolate.splev(x=s, tck=scipy.interpolate.splrep(speed, power, k=3))
lin = numpy.interp(s, speed, power)

输出结果:

print(cubic)
    nan

print(lin)
    24.02089607810346

问题原因

  • 重复节点导致样条生成失败:speed数组末尾存在两个完全相同的25.0,而三次样条插值要求输入节点必须是严格单调递增(或递减)且无重复值的。重复节点会让splrep无法生成有效样条曲线,最终splev无法计算出有效值,返回NaN。
  • 线性插值numpy.interp对重复节点兼容性更好,会自动忽略后续重复节点,仅保留第一个对应值,因此能正常输出结果。

解决方法

方法1:移除重复节点

先对speed和power数组去重,保留唯一节点及其对应值:

# 获取唯一节点的索引
unique_indices = numpy.unique(speed, return_index=True)[1]
# 按原顺序提取唯一的speed和power数组
unique_speed = speed[sorted(unique_indices)]
unique_power = power[sorted(unique_indices)]

# 重新执行三次样条插值
cubic = scipy.interpolate.splev(x=s, tck=scipy.interpolate.splrep(unique_speed, unique_power, k=3))
print(cubic)  # 输出:24.14632763573183

方法2:避免重复节点(根源解决)

在数据预处理阶段就排查并移除重复的输入节点,确保插值的节点数组严格单调,这是保证样条插值正常运行的前提。

验证说明

去重后unique_speed末尾仅保留一个25.0,此时splrep可正常生成三次样条曲线,splev能计算出s对应的插值结果,数值与线性插值接近但更贴合曲线趋势。

内容的提问来源于stack exchange,提问作者Nelson Salazar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 19:03:16