np.interp是NumPy内置的一维线性插值函数,要求x严格单调、无NaN,适用于轻量场景;对越界值默认平移边界值,不支持外推或自定义填充值。

用 np.interp 做一维线性插值最直接
NumPy 自带的 np.interp 就是专为一维线性插值设计的,不依赖 SciPy,启动快、无额外依赖,适合轻量级或嵌入式场景。它要求原始数据点 x 严格单调(升序或降序),否则结果不可靠,且只支持线性,不拟合曲线。
常见错误是把待插值坐标 xp 写成二维数组或含 nan —— np.interp 会静默失败或报 ValueError: array must be monotonic。
-
x和fp长度必须一致,且x必须单调(可用np.all(np.diff(x) > 0)检查) -
xp可以是标量、列表或一维数组;返回值形状与xp一致 - 超出
x范围的xp值默认按边界外推(即取最近端点值),不会报错但可能不符合预期
import numpy as np x = np.array([0, 1, 2, 3]) fp = np.array([0, 1, 4, 9]) # y = x² 的采样点 xp = np.array([-0.5, 1.5, 3.2]) result = np.interp(xp, x, fp) # → [0., 2.5, 9.]
处理非单调或含重复 x 坐标怎么办
如果原始数据来自传感器或日志,x 可能乱序、有重复或含 nan,直接传给 np.interp 会崩溃。不能跳过清洗,必须显式预处理。
- 先用
np.isnan(x) | np.isnan(fp)掩码剔除无效点 - 再用
np.unique(x, return_index=True)去重(保留首次出现位置),或用np.argsort(x)排序并同步重排fp - 若去重后只剩一个点,
np.interp会报错 —— 需提前判断长度是否 ≥ 2
x_raw = np.array([2, 0, 1, 2, 1])
fp_raw = np.array([4, 0, 1, 4, 1])
mask = ~np.isnan(x_raw) & ~np.isnan(fp_raw)
x_clean, idx = np.unique(x_raw[mask], return_index=True)
fp_clean = fp_raw[mask][idx]
# 确保单调:若 x_clean 是降序,翻转即可
if len(x_clean) > 1 and x_clean[0] > x_clean[-1]:
x_clean = x_clean[::-1]
fp_clean = fp_clean[::-1]
需要外推或边界填充值时别硬套 np.interp
np.interp 对范围外的 xp 总是“平移”边界值,无法做线性外推,也不能设 nan 或自定义填充。这时候得换方案。
- 简单外推:用
scipy.interpolate.interp1d并设fill_value="extrapolate"(注意它比np.interp慢约 3–5 倍) - 需填空值:先用
np.interp,再手动掩码xp超出[x.min(), x.max()]的位置,赋np.nan - 性能敏感又需外推?自己算斜率:对左右边界各拟一条直线,用
(xp - x_left) * slope + fp_left手动外推
和 scipy.interpolate.interp1d 比较时看清楚调用开销
很多人图省事直接上 interp1d,但它在每次调用前要构建插值对象,初始化成本高。如果只是单次插值,np.interp 快 10 倍以上;如果是多次复用同一组 x/fp 插不同 xp,interp1d 的缓存才体现价值。
-
np.interp是纯函数式,无状态,适合 pipeline 中单步计算 -
interp1d(kind="linear")返回可调用对象,内部缓存排序和差分,适合循环中反复调用 - 两者对输入容错性不同:
interp1d默认允许x乱序(自动排序),但会警告;np.interp直接报错
边界行为差异容易被忽略:比如 x=[0,1], fp=[10,20],当 xp=-1 时,np.interp 返回 10,而 interp1d(..., fill_value="extrapolate") 返回 0 —— 外推逻辑完全不同。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











