MATLAB interp2等效SciPy二维插值失效问题排查
解决MATLAB interp2到Python的2D插值转换问题
问题描述
需要将MATLAB的interp2插值逻辑转换为Python实现,原MATLAB代码:
Output = (interp2(X,Y,Tbl',Z,ThrtlPrcnt,'linear'));
Python中已准备好对应参数,期望输出为指定列向量,但使用SciPy的RectBivariateSpline、bisplrep/bisplev时均失败,其中RectBivariateSpline报错:
ValueError: x dimension of z must have same number of elements as x
已知一维插值中np.interp与MATLAB参数顺序不同,不清楚二维插值的参数对应关系。
已知参数
import numpy as np X = np.array([0, 550, 600, 700, 800, 874, 900, 950, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700, 1730, 2000, 2100, 2200, 2500, 3000], dtype=np.float64) Y = np.array([0, 1, 10, 20, 30, 40, 50, 70, 80, 100], dtype=np.float64) Tbl = np.array([[-75, -226, -239, -271, -375, -453, -701, -759, -818, -997], [-1269, -1716, -1967, -2028, -2056, -2104, -2106, -2124, -2130, -2137], [-2156, -2680, 463, -114, -166, -271, -375, -453, -701, -759], [-818, -997, -1269, -1716, -1967, -2028, -2056, -2104, -2106, -2124], [-2130, -2137, -2156, -2680, 954, 285, 285, 285, 285, 167], [125, 44, -32, -161, -290, -402, -521, -660, -800, -925], [-970, -1318, -1426, -1534, -1857, -2679, 1106, 535, 535, 535], [535, 417, 375, 294, 218, 89, -32, -152, -271, -391], [-510, -637, -670, -969, -1080, -1191, -1524, -2331, 1258, 860], [860, 860, 860, 809, 792, 759, 726, 648, 570, 500], [400, 300, 185, 81, 46, -271, -389, -506, -858, -1634], [1410, 1285, 1285, 1285, 1285, 1222, 1200, 1155, 1112, 1037], [965, 890, 800, 700, 600, 500, 470, 150, 0, -150], [-525, -1286, 1592, 1592, 1592, 1592, 1592, 1576, 1568, 1563], [1554, 1518, 1483, 1432, 1381, 1329, 1261, 1157, 1119, 776], [649, 522, 140, -590, 1867, 1944, 1937, 1924, 1910, 1901], [1897, 1895, 1893, 1887, 1849, 1815, 1781, 1747, 1620, 1516], [1477, 1125, 995, 864, 473, -242, 2019, 2144, 2137, 2124], [2130, 2145, 2150, 2150, 2150, 2150, 2150, 2150, 2150, 2120], [2009, 1880, 1850, 1550, 1420, 1290, 900, 200, 2383, 2536], [2550, 2578, 2606, 2626, 2634, 2648, 2648, 2648, 2648, 2648], [2620, 2520, 2369, 2234, 2193, 1823, 1686, 1549, 1139, 455]], dtype=np.float64) Z = np.array([600, 700, 800, 874, 900, 950, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700, 1730], dtype=np.float64) ThrtlPrcnt = 100.0
期望输出
np.array([[2550], [2578], [2606], [2626], [2634], [2648], [2648], [2648], [2648], [2648], [2620], [2520], [2369], [2234], [2193]])
错误原因
RectBivariateSpline的参数顺序与MATLABinterp2存在核心差异:
- MATLAB
interp2(X,Y,V,Xq,Yq)中,X对应V的列维度,Y对应V的行维度 - SciPy
RectBivariateSpline(x,y,z)中,x对应z的行维度,y对应z的列维度
之前报错是因为将X作为RectBivariateSpline的第一个参数,但Tbl.T(对应MATLAB的Tbl')的行维度长度为10(与Y长度一致),列维度长度为22(与X长度一致),参数顺序不匹配导致维度冲突。
解决方案
方案1:使用scipy.interpolate.interpn(更贴近MATLAB逻辑)
interpn的参数逻辑与interp2高度一致,直接指定维度坐标、值矩阵和查询点即可:
from scipy.interpolate import interpn # 构造查询点:每个Z元素与ThrtlPrcnt配对 xi = np.column_stack((Z, np.full_like(Z, ThrtlPrcnt))) # 执行线性插值:points为[X,Y]对应V的列、行维度,values为Tbl.T output = interpn([X, Y], Tbl.T, xi, method='linear') # 转换为期望的列向量格式 output = output.reshape(-1, 1)
方案2:修正RectBivariateSpline参数顺序
调整参数顺序,使坐标与矩阵维度匹配:
from scipy.interpolate import RectBivariateSpline # 创建插值器:x为Y(对应Tbl.T的行维度),y为X(对应Tbl.T的列维度) spline = RectBivariateSpline(Y, X, Tbl.T) # 查询:x取ThrtlPrcnt,y取Z,转置得到列向量 output = spline(ThrtlPrcnt, Z).T
两种方案均能得到与期望一致的输出结果。
内容的提问来源于stack exchange,提问作者Dipak
相关产品推荐
相关产品推荐

