pipe
pipe

Reputation: 737

What's the function object alternative to 1D linear interpolation with SciPy/NumPy?

I'm looking for a way to create a "functor" for linear interpolation of time,value pairs using SciPy (or NumPy) but according to the SciPy tutorial there is none! (Kind of the opposite of Trying to understand scipy and numpy interpolation)

The natural method would be interp1d but that has a warning:

Legacy This class is considered legacy and will no longer receive updates. […] For a guide to the intended replacements for interp1d see 1-D interpolation.

Following the link takes me to a page that tells me:

If all you need is a linear (a.k.a. broken line) interpolation, you can use the numpy.interp routine.

The problem is, these are not at all equivalent. numpy.interp requires me to know the points beforehand, and does not return a function that can be used to look up the interpolated values.

Meanwhile, SciPy has a number of other interpolation methods that all return a function (or a function object) such as CubicSpline or PchipInterpolator.

What's the easy way to construct a function or object similar to what PchipInterpolator returns, but for simple linear interpolation now that interp1d is deprecated?

Upvotes: 1

Views: 267

Answers (2)

jared
jared

Reputation: 9046

You can use scipy.interpolate.make_interp_spline with k=1 for linear interpolation.

import numpy as np
from scipy.interpolate import make_interp_spline, interp1d
import matplotlib.pyplot as plt

plt.close("all")

x = np.linspace(0, 20, 10)
y = np.cos(x**2)/(x+1)

x_fine = np.linspace(0, 20, 100)
y_np = np.interp(x_fine, x, y)
f_sp1 = make_interp_spline(x, y, k=1)
y_sp1 = f_sp1(x_fine)
f_sp2 = interp1d(x, y)
y_sp2 = f_sp2(x_fine)

fig, ax = plt.subplots()
ax.plot(x, y, ".", label="Original")
ax.plot(x_fine, y_np, label="Numpy")
ax.plot(x_fine, y_sp1, label="Scipy (make_interp_spline)")
ax.plot(x_fine, y_sp2, label="Scipy (interp1d)")
ax.legend()
fig.show()

Upvotes: 2

Krishnadev N
Krishnadev N

Reputation: 518

Just wrap numpy.interp in a function if you need to. Recreating the example in the official documentation using numpy.interp:

import numpy as np
from scipy import interpolate

x = np.arange(0, 10)
y = np.exp(-x/3.0)

f1 = interpolate.interp1d(x, y)
def f2(i):
    return np.interp(i, x, y)

xnew = np.arange(0, 9, 0.1)
np.isclose(f1(xnew), f2(xnew))    # Returns True

You may add the data points inside the function definition and construct "functors" for each case you have.

Alternatively:

from functools import partial

f2 = partial(np.interp, xp=x, fp=y)

You can even create a "functor", similar to scipy.interpolate.interp1d:

from functools import partial

def interp1d(x, y):
    return partial(np.interp, xp=x, fp=y)

f2 = interp1d(x, y)

Upvotes: 2

Related Questions