我在网格点z
处从2D函数f
采样数据x, y
,与z = f(x, y)
一样。
很容易通过f
与scipy.interp2d
插入f = interp2d(x, y, z
。
但是,评估f(x, y)
会返回整个2D网格,就像我已经完成
xx, yy = np.meshgrid(x, y)
f(xx, yy)
我想要的行为是简单地返回值[f(x[i], y[i]) for i in range(len(x))]
,我认为这几乎是numpy中任何其他方法的行为。
我想要这种行为的原因是我正在寻找f
表面上追踪的路径" time"由(t, u(t))
对组成。
同样令人惊讶的是np.diag(f(t, u(t)))
与np.array([f(ti, u(ti)) for ti in t])
不同,所以我不清楚如何通过{{1}返回的路径f(t, u(t))
}}
编辑:关于interp2d
,我只是认为我们应该diag
,但事实并非如此。
完整示例:
np.diag(f(t, u(t))) == np.array([f(ti, u(ti)) for ti in t])
我希望两个def f(t, u):
return (t**2) * np.exp((u**2) / (1 + u**2))
x = np.linspace(0, 1, 250)
xx, yy = np.meshgrid(x, x)
z = f(xx, yy)
f = scipy.interpolate.interp2d(x, y, z)
print(f(x, y))
print(np.array([f(xi, yi)[0] for xi, yi in zip(x, y)]))
语句的输出都相同。
答案 0 :(得分:3)
方法interp2d
返回一个对象,其调用方法要求x,y向量为矩形网格的坐标。并且你没有从返回数组的对角线获得所需值的原因是它首先对x,y进行排序。
但有一种解决方法,我也在Querying multiple points on a bivariate spline in the B-spline basis中使用过。执行后
import scipy.interpolate as si
f = si.interp2d(x, y, z)
不是通过调用来评估f,而是将其tck
属性,后跟x,y坐标传递给内部bispeu
方法。像这样:
print(si.dfitpack.bispeu(f.tck[0], f.tck[1], f.tck[2], f.tck[3], f.tck[4], x, y)[0])
以上返回与慢循环
相同print(np.array([f(xi, yi)[0] for xi, yi in zip(x, y)]))
对象f
秘密地是阶数为1的B样条。样条参数(节点,系数,顺序)包含在其tck
属性中,可以由低阶例程直接使用达到预期的效果。
(理想情况下,f
的调用方法会有一个布尔参数grid
,我们将其设置为False,让它知道我们不想要网格评估。唉,它没有实现。)
答案 1 :(得分:0)
interp2d()
似乎表现得如此,因为这就是相应的Fortran函数的构思方式。对此(我能想到的)唯一的解决方法是在坐标对上调用f
:
[f(*p)[0] for p in zip(x, y)]
答案 2 :(得分:0)
根据user6655984的建议,我在另一个thread中发布了以下包装函数:
import scipy.interpolate as si
def interp2d_pairs(*args,**kwargs):
""" Same interface as interp2d but the returned interpolant will evaluate its inputs as pairs of values.
"""
# Internal function, that evaluates pairs of values, output has the same shape as input
def interpolant(x,y,f):
x,y = np.asarray(x), np.asarray(y)
return (si.dfitpack.bispeu(f.tck[0], f.tck[1], f.tck[2], f.tck[3], f.tck[4], x.ravel(), y.ravel())[0]).reshape(x.shape)
# Wrapping the scipy interp2 function to call out interpolant instead
return lambda x,y: interpolant(x,y,si.interp2d(*args,**kwargs))
# Create the interpolant (same interface as interp2d)
f = interp2d_pairs(X,Y,Z,kind='cubic')
# Evaluate the interpolant on each pairs of x and y values
z=f(x,y)