Python如何基于scipy/pandas实现固定顺序多列线性插值
实现方案
你描述的是规则网格下的逐维顺序线性插值,scipy 提供了开箱即用的标准实现,pandas 无对应内置接口,可通过简单封装实现相同逻辑。
scipy 标准实现
直接使用 scipy.interpolate.RegularGridInterpolator 即可,该接口的默认线性插值逻辑和你列出的4步执行流程完全一致,不需要手动编写逐维插值逻辑。
import pandas as pd import numpy as np from scipy.interpolate import RegularGridInterpolator # 原始输入数据 df = pd.DataFrame({ 'x':[1,1,1,2,2,2], 'y':[1,2,3,1,2,3], 'z':[10,20,30,40,50,60] }) # 提取各维度有序唯一值(适配你提到的「输入数据预先排序」前提) x_coords = np.sort(df['x'].unique()) y_coords = np.sort(df['y'].unique()) # 将z值重构为和维度匹配的网格结构 z_mesh = df['z'].values.reshape(len(x_coords), len(y_coords)) # 初始化线性插值器 interpolator = RegularGridInterpolator((x_coords, y_coords), z_mesh, method='linear') # 计算目标点结果 print(interpolator((1.5, 2.5))) # 输出 40.0,和预期结果完全匹配
这个方案天然支持2维以上的同逻辑插值,只需要按顺序传入各维度坐标和对应网格值即可,不需要额外修改逻辑。
pandas 手动实现
如果不想引入scipy依赖,可以按照你描述的流程基于numpy的一维插值接口封装,逻辑完全透明:
import numpy as np def seq_linear_interp(df, target_x, target_y): # 查找x维度包围目标值的邻接点 x_unique = df['x'].drop_duplicates().to_list() x_lower = max(v for v in x_unique if v <= target_x) x_upper = min(v for v in x_unique if v >= target_x) # 固定x为下界值,做y维度插值 df_xl = df[df['x'] == x_lower] z_xl = np.interp(target_y, df_xl['y'], df_xl['z']) # 固定x为上界值,做y维度插值 df_xu = df[df['x'] == x_upper] z_xu = np.interp(target_y, df_xu['y'], df_xu['z']) # 最后做x维度插值得到最终结果 return np.interp(target_x, [x_lower, x_upper], [z_xl, z_xu]) # 测试调用 print(seq_linear_interp(df, 1.5, 2.5)) # 输出 40.0
补充说明
RegularGridInterpolator仅适用于规则网格数据,也就是所有维度坐标的笛卡尔组合都存在对应观测值,你的示例数据完全满足该要求。- pandas 自带的
df.interpolate()方法仅支持沿单轴方向的空值填充插值,无法直接处理这种多维网格的逐维插值场景。
内容的提问来源于stack exchange,提问作者Octan
相关产品推荐
相关产品推荐

