Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

numpy: how interpolate between two arrays for various timesteps?

I'm looking for a way to do a simple linear interpolation between two numpy arrays that represent a start and endpoint in time.

The two arrays have the same length:

fst = np.random.random_integers(5, size=(10.))
>>> array([4, 4, 1, 3, 1, 4, 3, 2, 5, 2])
snd = np.random.random_integers(5, size=(10.))
>>> array([1, 1, 3, 4, 1, 5, 5, 5, 4, 3])

Between my start and endpoint there are 3 timesteps. How can I interpolate between fst and snd? I want to be able, taking the first entry of fst and snd as an example, to retrieve the value of each timestep like

np.interp(1, [1,5], [4,1])    
np.interp(2, [1,5], [4,1])
...
# that is
np.interp([1,2,3,4,5], [1,5], [4,1])
>>> array([ 4.  ,  3.25,  2.5 ,  1.75,  1.  ])

But than not just for the first entry but over the whole array.

Obviously, this won't do it:

np.interp(1, [1,5], [fst,snd])

Well I know I get there in a loop, e.g.

[np.interp(2, [1,5], [item,snd[idx]]) for idx,item in enumerate(fst)]
>>> [3.25, 3.25, 1.5, 3.25, 1.0, 4.25, 3.5, 2.75, 4.75, 2.25]

but I believe when you are lopping over numpy arrays you are doing something fundamentally wrong.

like image 209
LarsVegas Avatar asked Apr 04 '16 09:04

LarsVegas


People also ask

How do you interpolate multiple values?

To interpolate in Excel, use the XLOOKUP function to find the x-values on either side of the input value of x as well as the corresponding y-values.

How does Numpy interp work?

interp() function returns the one-dimensional piecewise linear interpolant to a function with given discrete data points (xp, fp), evaluated at x. Parameters : x : [array_like] The x-coordinates at which to evaluate the interpolated values.

What is interpolated array?

Array interpolation provides a model or transformation between the true and a desired array response. If the true response of the array becomes more distorted with respect to the desired one or the considered region of the field of view of the array increases, nonlinear approaches become necessary.


1 Answers

The facilities in scipy.interpolate.interp1d allow this to be done quite easily if you form your samples into a 2D matrix. In your case, you can construct a 2xN array, and construct an interpolation function that operates down the columns:

from scipy.interpolate import interp1d
fst = np.array([4, 4, 1, 3, 1, 4, 3, 2, 5, 2])
snd = np.array([1, 1, 3, 4, 1, 5, 5, 5, 4, 3])
linfit = interp1d([1,5], np.vstack([fst, snd]), axis=0)

You can then generate an interpolated vector at any time of interest. For example linfit(2) produces:

array([ 3.25,  3.25,  1.5 ,  3.25,  1.  ,  4.25,  3.5 ,  2.75,  4.75,  2.25])

or you can invoke linfit() with a vector of time values, e.g. linfit([1,2,3]) gives:

array([[ 4.  ,  4.  ,  1.  ,  3.  ,  1.  ,  4.  ,  3.  ,  2.  ,  5.  ,  2.  ],
       [ 3.25,  3.25,  1.5 ,  3.25,  1.  ,  4.25,  3.5 ,  2.75,  4.75,           2.25],
       [ 2.5 ,  2.5 ,  2.  ,  3.5 ,  1.  ,  4.5 ,  4.  ,  3.5 ,  4.5 , 2.5 ]])

If you're only doing linear interpolation, you could also just do something like:

((5-t)/(5-1)) * fst + ((t-1)/(5-1)) * snd

to directly compute the interpolated vector at any time t.

like image 117
rwp Avatar answered Oct 05 '22 07:10

rwp