Skip to main content
added 1079 characters in body
Source Link
Reinderien
  • 65.5k
  • 5
  • 70
  • 188

I'll post some more detailed example codeHowever, all of that can be replaced with a call to interp1d:

import numpy as np
from scipy.interpolate import interp1d


def interpolate_arrays(bounds, n_steps=10):
    """final function that interpolates arrays"""
    bounds = np.array(bounds)

    fun = interp1d(
        x=[0, 1],
        y=bounds.T,
    )
    y = fun(np.linspace(0, 1, n_steps))

    return y


def test():
    X1 = [1.5, 1]
    X2 = [5.5, 3]

    y = interpolate_arrays([X1, X2], n_steps=3)
    assert y.T.tolist() == [[1.5, 1.0], [3.5, 2.0], [5.5, 3.0]]

Even easier:

def interpolate_arrays(X1, X2, n_steps=10):
    """final function that interpolates arrays"""
    return np.linspace(X1, X2, n_steps)


def test():
    X1 = [1.5, 1]
    X2 = [5.5, 3]

    y = interpolate_arrays(X1, X2, n_steps=3)
    assert y.tolist() == [[1.5, 1.0], [3.5, 2.0], [5.5, 3.0]]

Notes:

  • If you use interp1d, it would be better if your inputs and outputs are both two-dimensional np.ndarray; in their current form they need a transposition
  • Write some unit tests such as the one shown, although it would be a better idea to call isclose since this is floating-point math
  • If you want, it is trivial to make this extrapolate as well as interpolate

Basically: if there is a math thing in your head, before even thinking about what it would take to implement it yourself, do a bitsearch through scipy/numpy to see if it has already been done for you.

I'll post some more detailed example code in a bit.

However, all of that can be replaced with a call to interp1d:

import numpy as np
from scipy.interpolate import interp1d


def interpolate_arrays(bounds, n_steps=10):
    """final function that interpolates arrays"""
    bounds = np.array(bounds)

    fun = interp1d(
        x=[0, 1],
        y=bounds.T,
    )
    y = fun(np.linspace(0, 1, n_steps))

    return y


def test():
    X1 = [1.5, 1]
    X2 = [5.5, 3]

    y = interpolate_arrays([X1, X2], n_steps=3)
    assert y.T.tolist() == [[1.5, 1.0], [3.5, 2.0], [5.5, 3.0]]

Even easier:

def interpolate_arrays(X1, X2, n_steps=10):
    """final function that interpolates arrays"""
    return np.linspace(X1, X2, n_steps)


def test():
    X1 = [1.5, 1]
    X2 = [5.5, 3]

    y = interpolate_arrays(X1, X2, n_steps=3)
    assert y.tolist() == [[1.5, 1.0], [3.5, 2.0], [5.5, 3.0]]

Notes:

  • If you use interp1d, it would be better if your inputs and outputs are both two-dimensional np.ndarray; in their current form they need a transposition
  • Write some unit tests such as the one shown, although it would be a better idea to call isclose since this is floating-point math
  • If you want, it is trivial to make this extrapolate as well as interpolate

Basically: if there is a math thing in your head, before even thinking about what it would take to implement it yourself, do a search through scipy/numpy to see if it has already been done for you.

Source Link
Reinderien
  • 65.5k
  • 5
  • 70
  • 188

There are some easy wins here. Your interpolate_points doesn't need a loop:

def interpolate_points(p1, p2, n_steps=3):
    """Helper function that calculates the interpolation between two points"""
    # interpolate ratios between the points
    ratios = np.linspace(0, 1, num=n_steps)
    # linear interpolate vectors
    vectors = (1.0 - ratios) * p1 + ratios * p2
    return vectors

Also, even without further vectorization, you should be making use of range in your main function:

def interpolate_arrays(start_array, end_array, n_steps=10):
    """final function that interpolates arrays"""
    array_interpolation = []
    for n in range(n_steps):
        x = []
        for i in range(len(start_array)):
            e = interpolate_points(start_array[i], end_array[i], n_steps)[n]
            x.append(e)
        array_interpolation += [x]
    return array_interpolation

I'll post some more detailed example code in a bit.