二维插值应使用scipy.interpolate.griddata(散点)或RegularGridInterpolator(规则网格),不可用numpy.interp;前者要求输入坐标为(N,2)数组,后者需(y,x)顺序且Z形状为(len(y),len(x))。

二维插值用 scipy.interpolate.griddata,不是 numpy.interp
numpy.interp 只支持一维插值,直接对二维数据调用会报错 ValueError: object of too small depth for desired array。NumPy 本身不提供二维插值函数,必须借助 SciPy 的 griddata 或 RegularGridInterpolator。
常见误操作是试图用 np.meshgrid 搭配 np.interp 手动“逐行插值”,结果坐标映射错乱、边界失真,且无法处理非规则网格。
- 规则网格(等距、矩形)→ 优先用
scipy.interpolate.RegularGridInterpolator,速度快、内存友好 - 散点数据(如实验测量点、不规则采样)→ 必须用
scipy.interpolate.griddata - 不要尝试用
np.vectorize包裹一维插值函数来“模拟”二维,它不保证几何一致性
规则网格插值:用 RegularGridInterpolator 配合 np.mgrid
输入必须是严格单调的 1D 坐标数组(x, y)和对应形状为 (len(y), len(x)) 的值矩阵 Z。顺序不能颠倒:y 在前(行方向),x 在后(列方向)。
示例:已知 x = [0, 1, 2], y = [0, 1],Z = [[1, 2, 3], [4, 5, 6]],要查点 (0.5, 0.5):
立即学习“Python免费学习笔记(深入)”;
from scipy.interpolate import RegularGridInterpolator import numpy as np <p>x = np.array([0, 1, 2]) y = np.array([0, 1]) Z = np.array([[1, 2, 3], [4, 5, 6]]) # shape == (len(y), len(x))</p><p>interp_func = RegularGridInterpolator((y, x), Z) # 注意:(y, x),不是 (x, y) result = interp_func([[0.5, 0.5]]) # 输入是 [[y1,x1], [y2,x2], ...]</p>
- 插值点必须是 shape
(n, 2)的二维数组,哪怕只查一个点也要写成[[y, x]] - 超出原始网格范围时默认报错,加参数
bounds_error=False, fill_value=np.nan可静默处理 - 方法默认是
'linear',也可选'nearest'或'cubic'(后者要求网格至少 4 点)
散点插值:用 griddata 时注意输入维度和 method 选择
griddata 接收原始散点坐标 (xi, yi) 和对应值 zi,输出在目标网格上的插值结果。关键陷阱是输入格式:坐标必须拼成 (N, 2) 的二维数组,不能传两个一维数组。
错误写法:griddata(x, y, z, ...) → 报错 TypeError: griddata() takes from 3 to 4 positional arguments
正确写法:
from scipy.interpolate import griddata import numpy as np <h1>原始散点(N 个)</h1><p>points = np.column_stack((x_obs, y_obs)) # shape (N, 2) values = z_obs # shape (N,)</p><h1>目标网格(用 meshgrid 生成后展平)</h1><p>xi, yi = np.meshgrid(x_new, y_new, indexing='ij') xi_flat, yi_flat = xi.ravel(), yi.ravel() grid_points = np.column_stack((xi_flat, yi_flat)) # shape (M, 2)</p><p>zi_interp = griddata(points, values, grid_points, method='linear') zi_interp = zi_interp.reshape(xi.shape) # 恢复为二维</p>
-
method='linear'最常用,但要求原始点至少构成一个三角形;点太少或共线会返回nan -
method='nearest'总能返回值,但结果呈块状,无平滑性 -
method='cubic'仅适用于 2D,且对点分布敏感,稀疏区域易震荡 - 原始点数少于 10 个时,
linear和cubic都可能失效,应改用nearest或补采样
性能与内存:避免在循环里反复创建插值对象
如果需要对同一组原始数据做多次查询(比如动画帧、参数扫描),不要每次调用都新建 RegularGridInterpolator 或重复调用 griddata —— 前者初始化开销小但反复构造仍浪费,后者每次都要重新 Delaunay 三角剖分,极慢。
- 规则网格:构建一次
RegularGridInterpolator实例,反复调用__call__ - 散点数据:若查询点固定,可先用
griddata一次性插值到完整网格;若查询点动态变化且量大,考虑用scipy.interpolate.LinearNDInterpolator(缓存三角剖分) - 内存上,
griddata对百万级原始点会吃掉数 GB 内存,此时应降采样或改用径向基函数(RBF)等替代方案
二维插值真正的复杂点不在代码几行,而在于原始数据的几何质量:坐标是否覆盖目标区域、有无空洞、密度是否足够支撑所选 method。跑通代码只是第一步,结果是否可信,得看散点分布图和残差热力图。


















