SciPy interp2D用于坐标对

时间:2016-02-12 10:53:29

标签: python scipy interpolation

我使用scipy.interpolate.interp2d为曲面创建插值函数。然后,我有两个真实数据数组,我想计算插值点。如果我将两个数组传递给interp2d函数,我会获得所有点的数组,而不仅仅是点对。

我的解决方法是将两个数组压缩成一个坐标对列表,并将其传递给循环中的插值函数:

f_interp = interpolate.interp2d(X_table, Y_table,Z_table, kind='cubic')

co_ords = zip(X,Y)
out = []
for i in range(len(co_ords)):
    X = co_ords[i][0]
    Y = co_ords[i][1]
    value = f_interp(X,Y)
    out.append(float(value))

我的问题是,是否有更好的(更优雅的,Pythonic?)方式来实现相同的结果?

4 个答案:

答案 0 :(得分:3)

Passing all of your points at once will probably be quite a lot faster than looping over them in Python. You could use scipy.interpolate.griddata:

GIDSignInUIDelegate

or one of the Z = interpolate.griddata((X_table, Y_table), Z_table, (X, Y), method='cubic') classes, e.g. SmoothBivariateSpline:

scipy.interpolate.BivariateSpline

CloughTocher2DInterpolator also works in a similar fashion, but without the itp = interpolate.SmoothBivariateSpline(X_table, Y_table, Z_table) # NB: choose grid=False to get an (n,) rather than an (n, n) output Z = itp(X, Y, grid=False) parameter (it always returns a 1D output).

答案 1 :(得分:2)

尝试* args和tuple打包/解包

points = zip(X, Y)
out = []
for p in points:
    value = f_interp(*p)
    out.append(float(value))

或只是

points = zip(X, Y)
out = [float(f_interp(*p)) for p in points]

或只是

out = [float(f_interp(*p)) for p in zip(X, Y)]

作为旁注,"魔术明星"允许zip成为它自己的反转!

points = zip(x, y)
x, y   = zip(*points)

答案 2 :(得分:1)

首先,你可以做到

for Xtmp,Ytmp in zip(X,Y):
    ...
你的循环中的

。或者甚至更好,只是

out = [float(f_interp(XX,YY)) for XX,YY in zip(X,Y)]

更换循环。

另一方面,I suggest using interpolate.griddata代替。它往往比interp2d表现得更好,并且它接受任意形状的点作为输入。如您所见,interp2d插值器只返回网格上的值。

答案 3 :(得分:0)

受此thread的启发(有人建议使用interp2d函数的内部权重),我创建了以下包装器,该包装器具有与interp2d完全相同的接口,但内插器评估输入对和返回其输入形状相同的numpy数组。性能应该比for循环或列表理解要好,但是在网格上进行评估时,它的表现将比interp2d稍好。

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)