简体   繁体   中英

Scipy interpolate on structured 2d data, but evaluate at unstructured points?

I have the following minimum code using scipy.interpolate.interp2d to do interpolation on 2d grid data.

import numpy as np
from scipy import interpolate
x = np.arange(-5.01, 5.01, 0.25)
y = np.arange(-5.01, 5.01, 0.25)
xx, yy = np.meshgrid(x, y)
z = np.sin(xx**2+yy**2)
f = interpolate.interp2d(x, y, z, kind='cubic')

Now f here can be used to evaluate other points. The problem is the points I want to evaluate are totally random points not forming a regular grid.

# Evaluate at point (x_new, y_new), in total 256*256 points
x_new = np.random.random(256*256)
y_new = np.random.random(256*256)
func(x_new, y_new)

This will cause a runtime error in my PC, it seems to treat x_new and y_new as mesh grid, generate a evaluation matrix 65536x65536, which is not my purpose.

RuntimeError: Cannot produce output of size 65536x65536 (size too large)

One way to get things done is to evaluate points one by one , using code:

z_new = np.array([f(i, j) for i, j in zip(x_new, y_new)])

However, it is slow !!!

%timeit z_new = np.array([f(i, j) for i, j in zip(x_new, y_new)])

1.26 s ± 46.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

Is there any faster way to evaluate random points?

Faster here I mean comparable with time below:

x_new = np.random.random(256)
y_new = np.random.random(256)

%timeit f(x_new, y_new)

Same 256*256 = 65536 evaluations, time for this in my PC:

1.21 ms ± 39.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

It does not have to be in comparable speed with 1.21ms, 121 ms is totally acceptable.

The function you are looking for is scipy.interpolate.RegularGridInterpolator

Given a set of points (x,y,z), where x & y are defined on a regular grid, it allows you to sample the z-value of intermediate (x,y) points. In your case, this would look as follows

import numpy as np
from scipy import interpolate
x = np.arange(-5.01, 5.01, 0.25)
y = np.arange(-5.01, 5.01, 0.25)

def f(x,y):
    return np.sin(x**2+y**2)

z = f(*np.meshgrid(x, y, indexing='ij', sparse=True))
func = interpolate.RegularGridInterpolator((x,y), z)

x_new = np.random.random(256*256)
y_new = np.random.random(256*256)
xy_new = list(zip(x_new,y_new))
z_new = func(xy_new)func(xy_new)

For more details, see https://docs.scipy.org/doc/scipy-0.16.1/reference/generated/scipy.interpolate.RegularGridInterpolator.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM