SciPy interp2D 用于坐标对的插值

12

我正在使用 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))

我的问题是,是否有更好(更优雅、更符合Python风格)的方法来实现相同的结果?

4个回答

4

一次性传递所有数据点可能比在Python中循环它们要快得多。你可以使用scipy.interpolate.griddata

Z = interpolate.griddata((X_table, Y_table), Z_table, (X, Y), method='cubic')

或者使用scipy.interpolate.BivariateSpline类之一,例如SmoothBivariateSpline
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)

CloughTocher2DInterpolator 的工作方式类似,但没有grid=False参数(它始终返回 1D 输出)。


2
尝试使用*args和元组打包/解包技术。
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)

1
一方面,您可以执行以下操作:
for Xtmp,Ytmp in zip(X,Y):
    ...

在你的循环中。或者更好的方法是,只需使用HTML标签


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

替换循环。
另外,我建议使用interpolate.griddata。它的表现比interp2d好得多,并且它接受任意形状的点作为输入。正如你所看到的,interp2d插值器只会在网格上返回值。

0
受到thread的启发,其中有人建议使用interp2d函数的内部权重,我创建了以下包装器,其接口与interp2d完全相同,但插值器评估输入对并返回与其输入形状相同的numpy数组。性能应该比for循环或列表理解更好,但在网格上评估时,它将略逊于scipy 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)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接