Python 3d interpolation irregular grid

I found the answer, and posting it for the benefit of StackOverflow readers.

The method is as follows:

1- Imports:

import numpy as np
from scipy.interpolate import griddata
from scipy.interpolate import LinearNDInterpolator

2- prepare the data as follows:

# put the available x,y,z data as a numpy array
points = np.array[[
        [ 27.827,  18.53 , -30.417], [ 24.002,  17.759, -24.782],
        [ 22.145,  13.687, -33.282], [ 17.627,  18.224, -25.197],
        [ 29.018,  18.841, -38.761], [ 24.834,  20.538, -33.012],
        [ 26.232,  22.327, -27.735], [ 23.017,  23.037, -29.23 ],
        [ 28.761,  21.565, -31.586], [ 26.263,  23.686, -32.766]]]
# and put the moisture corresponding data values in a separate array:
values = np.array[[0.205,  0.197,  0.204,  0.197,  0.212,  
                   0.208,  0.204,  0.205, 0.211,  0.215]]
# Finally, put the desired point/points you want to interpolate over
request = np.array[[[25, 20, -30], [27, 20, -32]]]

3- Write the final line of code to get the interpolated values

Method 1, using griddata

print griddata[points, values, request]
# OUTPUT: array[[ 0.20448536, 0.20782028]]

Method 2, using LinearNDInterpolator

# First, define an interpolator function
linInter= LinearNDInterpolator[points, values]

# Then, apply the function to one or more points
print linInter[np.array[[[25, 20, -30]]]]
print linInter[request]
# OUTPUT: [0.20448536  0.20782028]
# I think you may use it with python map or pandas.apply as well

Hope this benefit every one.

Bet regards

For scattered data at points with no structure, try inverse-distance-weighted-idw-interpolation-with-python. This combines scipy's fast K-d_trees with inverse-distance aka radial kernels:

$\qquad interpol[ x ] = \sum w_i \, f_i$, sum over say 10 points nearest $x$
$\qquad \qquad \qquad \qquad w_i = {1 \over |x - x_i|^p}$ normalized so $\sum w_i = 1$ .
It's only 40 lines of code, so easy to understand and modify. Runtimes on a stock iMac:
0.2 sec to build a Kd tree for 170k points in 3d
25 sec to query 100k points.

For rectangular grids aka box grids in 2d, 3d and up, data at e.g. $m \times n \times k$ points $[x_i, y_j, z_k]$ with no NAs, see Intergrid, a wrapper for scipy.ndimage.map_coordinates.

[Needless to say, it's a good idea to check any interpolation. An easy method is to split the data into say 90 % $train$ + 10 % $test$ points, and compare $interpolate[ \, train \to test \, ]$ with $true[ \, test \, ]$ .]

See also:
gis.stackexchange.com/questions/tagged/interpolation+python on gis.stack
how-to-interpolate-scattered-data-to-a-regular-grid-in-python on earthscience.stack
pyresample, pyproj .

scipy.interpolate.griddata[points, values, xi, method='linear', fill_value=nan, rescale=False][source]#

Interpolate unstructured D-D data.

Parameterspoints2-D ndarray of floats with shape [n, D], or length D tuple of 1-D ndarrays with shape [n,].

Data point coordinates.

valuesndarray of float or complex, shape [n,]

Data values.

xi2-D ndarray of floats with shape [m, D], or length D tuple of ndarrays broadcastable to the same shape.

Points at which to interpolate data.

method{‘linear’, ‘nearest’, ‘cubic’}, optional

Method of interpolation. One of

nearest

return the value at the data point closest to the point of interpolation. See NearestNDInterpolator for more details.

linear

tessellate the input point set to N-D simplices, and interpolate linearly on each simplex. See LinearNDInterpolator for more details.

cubic [1-D]

return the value determined from a cubic spline.

cubic [2-D]

return the value determined from a piecewise cubic, continuously differentiable [C1], and approximately curvature-minimizing polynomial surface. See CloughTocher2DInterpolator for more details.

fill_valuefloat, optional

Value used to fill in for requested points outside of the convex hull of the input points. If not provided, then the default is nan. This option has no effect for the ‘nearest’ method.

rescalebool, optional

Rescale points to unit cube before performing interpolation. This is useful if some of the input dimensions have incommensurable units and differ by many orders of magnitude.

New in version 0.14.0.

Returns ndarray

Array of interpolated values.

Notes

New in version 0.9.

Examples

Suppose we want to interpolate the 2-D function

>>> def func[x, y]:
...     return x*[1-x]*np.cos[4*np.pi*x] * np.sin[4*np.pi*y**2]**2

on a grid in [0, 1]x[0, 1]

>>> grid_x, grid_y = np.mgrid[0:1:100j, 0:1:200j]

but we only know its values at 1000 data points:

>>> rng = np.random.default_rng[]
>>> points = rng.random[[1000, 2]]
>>> values = func[points[:,0], points[:,1]]

This can be done with griddata – below we try out all of the interpolation methods:

>>> from scipy.interpolate import griddata
>>> grid_z0 = griddata[points, values, [grid_x, grid_y], method='nearest']
>>> grid_z1 = griddata[points, values, [grid_x, grid_y], method='linear']
>>> grid_z2 = griddata[points, values, [grid_x, grid_y], method='cubic']

One can see that the exact result is reproduced by all of the methods to some degree, but for this smooth function the piecewise cubic interpolant gives the best results:

>>> import matplotlib.pyplot as plt
>>> plt.subplot[221]
>>> plt.imshow[func[grid_x, grid_y].T, extent=[0,1,0,1], origin='lower']
>>> plt.plot[points[:,0], points[:,1], 'k.', ms=1]
>>> plt.title['Original']
>>> plt.subplot[222]
>>> plt.imshow[grid_z0.T, extent=[0,1,0,1], origin='lower']
>>> plt.title['Nearest']
>>> plt.subplot[223]
>>> plt.imshow[grid_z1.T, extent=[0,1,0,1], origin='lower']
>>> plt.title['Linear']
>>> plt.subplot[224]
>>> plt.imshow[grid_z2.T, extent=[0,1,0,1], origin='lower']
>>> plt.title['Cubic']
>>> plt.gcf[].set_size_inches[6, 6]
>>> plt.show[]

Chủ Đề