SciPy interp2D for pairs of coordinates

时光毁灭记忆、已成空白 提交于 2019-12-04 09:19:59
Andras Deak

For one, you can do

for Xtmp,Ytmp in zip(X,Y):
    ...

in your loop. Or even better, just

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

replacing the loop.

On a different note, I suggest using interpolate.griddata instead. It tends to behave much better than interp2d, and it accepts arbitrary-shaped points as input. As you've seen, interp2d interpolators will only return you values on a mesh.

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:

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

or one of the scipy.interpolate.BivariateSpline classes, e.g. 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 also works in a similar fashion, but without the grid=False parameter (it always returns a 1D output).

Try *args and tuple packing/unpacking

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

or just

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

or just

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

as a side note, the "magic star" allows zip to be its own inverse!

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

Inspired by this thread where someone recommends using the internal weights of the interp2d function, I've created the following wrapper which has exactly the same interface as interp2d but the interpolant evaluate pairs of inputs and return a numpy array of the same shape of its inputs. The performances should be better than for loops or list comprehension, but when evaluated on a grid it will be slightly outperformed by the 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)
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!