Interpolating data from a look up table

2019-01-15 07:33发布

问题:

read the look up table

LUT = np.genfromtxt('test.out', delimiter=',', dtype=float)
LUT:
    12, 25, 136, 6743
    13, 26, 139, 6786
    14, 27, 142, 6791
    15, 28, 145, 6789

Values to be read from the LUT are as follows:

x1, x2, x3 = 12.5, 25.5, 137

Reading the neighboring two values in the LUT for each of the given values (3 columns), I have to linearly interpolate the results (4th column in LUT).

The given values (x1, x2, x3) belongs to between 1st and 2nd row of the LUT. Based on this how to read the results between 1st and 2nd row?

回答1:

Given a list of coordinates coords where you want to interpolate, you can use scipy.spatial.cKDTree to obtain the 2 closest entries of your table that are necessary for the linear interpolation. The code below shows an usage example, already vectorized.

import numpy as np
from scipy.spatial import cKDTree

# inputs
LTU = np.genfromtxt('test.txt', delimiter=',')

coords = ((12.5, 25.5, 137),
          (13.5, 26.5, 141),
          (14.5, 25.5, 144))

# querying and interpolating
xyz = LTU[:, :3]
val = LTU[:, 3]

del LTU # attempt to clean up memory

tree = cKDTree(xyz)
dist, ind = tree.query(coords, k=2)

d1, d2 = dist.T
v1, v2 = val[ind].T
v = (d1)/(d1 + d2)*(v2 - v1) + v1

print(v)
#[ 6758.73909236  6789.16987298  6790.03575996]


回答2:

It is a little unclear - the context you are working with.

Provided this is a more general LUT: find the closest 2 points via the euclidian distance to all points in the the LUT from the provided point. After establishing those 2 points, use bilinear interpolation on the 4th column.

Now if each column increases in lock step w/ (1, 1, 3) and you have some notion of order here, find the upper and lower bounds with python's bisect module of the first column and you're done finding the indices you would interpolate with (bilinearlly?). Since you mention in the comments below the delta is fixed, this makes this far more a 1d LUT problem than a 3d problem - arguably you could use numpy.interp using just the first dimension and 4th dimension.

If they are not in lock step but a similar ordering is preserved, restrict the range of allowed upper and lower indices by producing a cumulative upper/lower bound across columns, then decide what indices you'd like to interpolate with over that range.

For all of these, if you find an exact value in the LUT, do not bother interpolating.