Search code examples
pythonnumpylinear-interpolation

Interpolation of arrays python


I have a program where I want the user to choose a temperature (T_user), whatever he wants. Knowing that I have a temperature array: T=np.array([10,20,30,50,100,150,200]). I have found a way to get the index and closest value for T_user compared to the values in T. I then have X=np.array([1,2,3,4,5,6]) and Y=np.array([3,6,9,12,15,18]) using numpy.interp(). Now lets say that T_user=12 and that X,Y are respectively linked to T[0]=10 and T[1]=20 how can I create a new array interpolated with X,T arrays and "the distance"/ratio from T_user to T[0]=10 and T[1]=20. Let me know if this is not clear at all.


Solution

  • You can use the apply_along_axis method:

    Code:

    import numpy as np
    
    T = np.array([10, 20, 30, 50, 100, 150, 200])
    W1 = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
    W2 = np.array([3, 6, 9, 12, 15, 18, 21, 24, 27, 30])
    
    T_user = 12
    
    # Get the neighbor values
    t1 = T[T<=T_user].max(initial=T.min())
    t2 = T[T_user<=T].min(initial=T.max())
    
    # Interpolate the values
    arr_interp = np.apply_along_axis(lambda e: np.interp(T_user, [t1, t2], e), 1, np.stack([W1, W2]).T)
    

    Tests:

    f = lambda t: np.apply_along_axis(lambda e: np.interp(t, [T[T<=t].max(initial=T.min()), T[t<=T].min(initial=T.max())], e), 1, np.stack([W1, W2]).T)
    
    T_user = 12
    np.testing.assert_array_equal(f(T_user), np.array([1.4, 2.8, 4.2, 5.6, 7.0, 8.4, 9.8, 11.2, 12.6, 14.0]))
    
    T_user = 15
    np.testing.assert_array_equal(f(T_user), np.array([ 2.,  4.,  6.,  8., 10., 12., 14., 16., 18., 20.]))
    
    T_user = 31
    np.testing.assert_array_equal(f(T_user), np.array([ 1.1,  2.2,  3.3,  4.4,  5.5,  6.6,  7.7,  8.8,  9.9, 11. ]))
    
    T_user = 0
    np.testing.assert_array_equal(f(T_user), np.array([ 1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10.]))
    
    T_user = 10
    np.testing.assert_array_equal(f(T_user), np.array([ 3.,  6.,  9., 12., 15., 18., 21., 24., 27., 30.]))
    
    T_user = 100
    np.testing.assert_array_equal(f(T_user), np.array([ 3.,  6.,  9., 12., 15., 18., 21., 24., 27., 30.]))
    
    T_user = 200
    np.testing.assert_array_equal(f(T_user), np.array([ 3.,  6.,  9., 12., 15., 18., 21., 24., 27., 30.]))
    
    T_user = 300
    np.testing.assert_array_equal(f(T_user), np.array([ 3.,  6.,  9., 12., 15., 18., 21., 24., 27., 30.]))
    

    Explanation:

    If you have a minimal sample dataset as follows, what is the interpolation going to be like in my implementation?

    T = np.array([10, 20])
    W1 = np.array([1,])
    W2 = np.array([3,])
    

    # Case.1 (T_user = 12)

    enter image description here

    # Case.2 (T_user = 5)

    enter image description here

    # Case.3 (T_user = 10)

    enter image description here

    # Case.4 (T_user = 25)

    enter image description here