! pip install numba
Requirement already satisfied: numba in /usr/local/lib/python3.6/dist-packages (0.38.1) Requirement already satisfied: llvmlite>=0.23.0dev0 in /usr/local/lib/python3.6/dist-packages (from numba) (0.23.2) Requirement already satisfied: numpy in /usr/local/lib/python3.6/dist-packages (from numba) (1.14.3)
from numba import guvectorize
import numpy as np
import scipy.interpolate
def _interp1d(xnew, xvals, yvals, ynew):
i = 0
N = len(xvals)
if xnew[0] < xvals[0]:
x_a = 0.0
y_a = 0.0
x_b = xvals[0]
y_b = yvals[0]
else:
while xnew[0] >= xvals[i] and i < N:
i += 1
if xnew[0] == xvals[i]:
ynew[0] = yvals[i]
return
if i == N:
i = N-1
x_a = xvals[i-1]
y_a = yvals[i-1]
x_b = xvals[i]
y_b = yvals[i]
slope = (xnew[0] - x_a)/(x_b - x_a)
ynew[0] = slope * (y_b-y_a) + y_a
return
interp1d_numba = guvectorize(
['float64[:], float64[:], float64[:], float64[:]'],
"(),(n),(n) -> ()", nopython=True)(_interp1d)
def _interp1d_np(xnew, xvals, yvals):
xnew = np.asarray(xnew)[..., np.newaxis]
out = np.empty_like(xnew)
_interp1d(xnew, xvals, yvals, out)
return out.squeeze(axis=-1)
interp1d_numpy = np.vectorize(_interp1d_np, signature='(),(n),(n)->()')
xnew = np.arange(900) / 900
xvals = yvals = np.arange(1000.0) / 1000
np.testing.assert_allclose(interp1d_numpy(xnew, xvals, yvals), scipy.interpolate.interp1d(xvals, yvals)(xnew))
np.testing.assert_allclose(interp1d_numba(xnew, xvals, yvals), scipy.interpolate.interp1d(xvals, yvals)(xnew))
%timeit interp1d_numpy(xnew, xvals, yvals)
10 loops, best of 3: 133 ms per loop
%timeit interp1d_numba(xnew, xvals, yvals)
The slowest run took 13.55 times longer than the fastest. This could mean that an intermediate result is being cached. 1000 loops, best of 3: 384 µs per loop
%timeit scipy.interpolate.interp1d(xvals, yvals)(xnew)
The slowest run took 51.79 times longer than the fastest. This could mean that an intermediate result is being cached. 10000 loops, best of 3: 89.1 µs per loop