简体   繁体   中英

How to use numpy to interpolate between pairs of values in a list

I have lists like these:

x_data = [3, 5, 7, 8, 5, 2]
y_data = [15, 20, 22, 23, 21, 14]

I'd like to interpolate between pairs of items in the list so that instead of have list of length 6, it's length n with equally space values between each pair of items within the list. My current approach is to use a list comprehension to go through pairs in the list and np.extend an empty list with the results. Is there a better, ready-made function to do this?

My current approach:

import numpy as np

x_data = [3, 5, 7, 8, 5, 2]
y_data = [15, 20, 22, 23, 21, 14]
result_x = []
result_y = []
[result_x.extend(np.linspace(first, second, 5)) for first, second, in  zip(x_data, x_data[1:])]
[result_y.extend(np.linspace(first, second, 5)) for first, second, in  zip(y_data, y_data[1:])]
print(result_x, '\n'*2, result_y)

Out: [3.0, 3.5, 4.0, 4.5, 5.0, 5.0, 5.5, 6.0, 6.5, 7.0, 7.0, 7.25, 7.5, 7.75, 8.0, 8.0, 7.25, 6.5, 5.75, 5.0, 5.0, 4.25, 3.5, 2.75, 2.0] 



[15.0, 16.25, 17.5, 18.75, 20.0, 20.0, 20.5, 21.0, 21.5, 22.0, 22.0, 22.25, 22.5, 22.75, 23.0, 23.0, 22.5, 22.0, 21.5, 21.0, 21.0, 19.25, 17.5, 15.75, 14.0]

I think this function does what you want using np.interp :

import numpy as np

def interpolate_vector(data, factor):
    n = len(data)
    # X interpolation points. For factor=4, it is [0, 0.25, 0.5, 0.75, 1, 1.25, 1.5, ...]
    x = np.linspace(0, n - 1, (n - 1) * factor + 1)
    # Alternatively:
    # x = np.arange((n - 1) * factor + 1) / factor
    # X data points: [0, 1, 2, ...]
    xp = np.arange(n)
    # Interpolate
    return np.interp(x, xp, np.asarray(data))

Example:

x_data = [3, 5, 7, 8, 5, 2]
y_data = [15, 20, 22, 23, 21, 14]

print(interpolate_vector(x_data, 4))
# [3.   3.5  4.   4.5  5.   5.5  6.   6.5  7.   7.25 7.5  7.75 8.   7.25
#  6.5  5.75 5.   4.25 3.5  2.75 2.  ]
print(interpolate_vector(y_data, 4))
# [15.   16.25 17.5  18.75 20.   20.5  21.   21.5  22.   22.25 22.5  22.75
#  23.   22.5  22.   21.5  21.   19.25 17.5  15.75 14.  ]

Scipy has an interpolation functions that will easily handle this type of approach. You just provide your current data and the new "x" values that the interpolated data will be based on.

from scipy import interpolate

x_data = [3, 5, 7, 8, 5, 2]
y_data = [15, 20, 22, 23, 21, 14]
t1 = np.linspace(0, 1, len(x_data))
t2 = np.linspace(0, 1, len(y_data))

n = 50
t_new = np.linspace(0, 1, n)

f = interpolate.interp1d(t1, x_data)
x_new = f(t_new)

f = interpolate.interp1d(t2, y_data)
y_new = f(t_new)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM