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

如何在不排序x数组的情况下使用make_interp_spline进行曲线插值?

解决make_interp_spline要求x有序无重复的问题

make_interp_spline的底层实现依赖严格单调且无重复的x数组,这是硬性要求,无法直接绕过。以下两种方案可以解决你的问题:

方案一:处理数据后继续使用make_interp_spline

如果你的需求是基于x的单值函数(每个x对应唯一y),需要先清理x数组的重复值,再排序:

  1. 去重并处理重复x对应的y:对相同x的y值取均值、中位数,或保留第一个/最后一个值(根据业务需求选择)
  2. 排序:将去重后的x和对应的y按x排序,满足make_interp_spline的输入要求

示例代码:

from scipy.interpolate import make_interp_spline
import numpy as np
import matplotlib.pyplot as plt

x = np.array([-31,-30,-30,-32,-36,-39])
y = np.array([60,62,64,65,64,64])

# 处理重复x:对相同x的y取均值
unique_x, indices = np.unique(x, return_inverse=True)
mean_y = np.bincount(indices, weights=y) / np.bincount(indices)

# 按x排序
sorted_idx = np.argsort(unique_x)
sorted_x = unique_x[sorted_idx]
sorted_y = mean_y[sorted_idx]

# 生成平滑曲线
X_Y_Spline = make_interp_spline(sorted_x, sorted_y)
X_ = np.linspace(sorted_x.min(), sorted_x.max(), 500)
Y_ = X_Y_Spline(X_)

# 绘图
plt.plot(x, y, 'o', label='原始点')
plt.plot(X_, Y_, label='平滑曲线')
plt.legend()
plt.show()

方案二:使用参数化样条插值(无需排序x)

如果只是要绘制经过原始点的平滑曲线(不要求x是函数的自变量),可以用splprep做参数化插值。它将曲线视为参数t的函数,不要求x有序或无重复:

示例代码:

from scipy.interpolate import splprep, splev
import numpy as np
import matplotlib.pyplot as plt

x = np.array([-31,-30,-30,-32,-36,-39])
y = np.array([60,62,64,65,64,64])

# 参数化拟合,s=0表示严格经过所有点,调大s可增加平滑度
tck, u = splprep([x, y], s=0)

# 生成更多采样点
u_new = np.linspace(u.min(), u.max(), 500)
x_new, y_new = splev(u_new, tck)

# 绘图
plt.plot(x, y, 'o', label='原始点')
plt.plot(x_new, y_new, label='平滑曲线')
plt.legend()
plt.show()

注意事项

  • 如果你的场景要求x作为自变量(即每个x对应唯一y值),必须选择方案一,因为函数的定义不允许x重复或无序
  • 方案二适合绘制路径类曲线,不关注x是否为单值自变量的场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 19:54:21