Reputation: 4546
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]
Upvotes: 1
Views: 1260
Reputation: 59731
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. ]
Upvotes: 1
Reputation: 10590
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)
Upvotes: 1