interpolate to specific time

房东的猫 提交于 2020-01-04 05:44:16

问题


Let's say I have this code:

import numpy as np
import time
from datetime import datetime

class Measurements():
    def __init__(self, time_var, value):
        self.time_var = time_var
        self.value = value

a = np.array([ Measurements('30-01-2017 12:02:15.880922', 100),
               Measurements('30-01-2017 12:02:16.880922', 100),
               Measurements('30-01-2017 12:02:17.880922', 110),
               Measurements('30-01-2017 12:02:18.880922', 99),
               Measurements('30-01-2017 12:02:19.880922', 96)])


b = np.array([ Measurements('30-01-2017 12:02:15.123444', 10),
               Measurements('30-01-2017 12:02:18.880919', 12),
              ])

So, I have 5 measurements from a and 2 from b.

I want, by using the a as base, to find the missing b values at the specific time where a happens.

So, the final b will always have the a time values and length.( for the time, I thought of taking the time.mktime(datetime.strptime(s, "%d-%m-%Y %H:%M:%S.%f").timetuple()) to return time in seconds

So, the b will be :

np.array([ Measurements('30-01-2017 12:02:15.880922', MISSING_VALUE),
               Measurements('30-01-2017 12:02:16.880922', MISSING_VALUE),
               Measurements('30-01-2017 12:02:17.880922', MISSING_VALUE),
               Measurements('30-01-2017 12:02:18.880922', MISSING_VALUE),
               Measurements('30-01-2017 12:02:19.880922', MISSING_VALUE)])

Now, I am not sure how to deal with this.

One thought is to execute first the interp as here and stretch the b length to be equal with a.

Or using interp1d (more flexible):

from scipy import interpolate

a = np.array([100, 123, 123, 118, 123])
b = np.array([12, 11, 14, 13])

b_interp = interpolate.interp1d(np.arange(b.size),b, kind ='cubic', assume_sorted=False)
b_new = b_interp(np.linspace(0, b.size-1, a.size))

But then , how to deal with the time?


回答1:


Here is the solution of your problem :

  • first, if you use cubic interpolation, you need at least 4 values for a and 4 values for b (scipy.interpolate.interp1d with kind="cubic" is not working otherwise)
  • second, you can not interpolate values with scipy.interpolate.interp1d that are not in the range you define (the range of b times)

I changed a bit your initial code to show you :

time_a_full = ['30-01-2017 12:02:15.880922','30-01-2017 12:02:16.880922','30-01-2017 12:02:17.880922','30-01-2017 12:02:18.880922','30-01-2017 12:02:19.880922','30-01-2017 12:02:22.880922']
time_b_full = ['30-01-2017 12:02:15.123444','30-01-2017 12:02:16.880919','30-01-2017 12:02:18.880920', '30-01-2017 12:02:19.880922','30-01-2017 12:02:20.880922']

# Here I transform the time in seconds as suggested
time_a = np.array([time.mktime(datetime.strptime(s, "%d-%m-%Y %H:%M:%S.%f").timetuple()) for s in time_a_full])
time_b = np.array([time.mktime(datetime.strptime(s, "%d-%m-%Y %H:%M:%S.%f").timetuple()) for s in time_b_full])

values_a = np.array([100,100,110,99,96,95])
values_b = np.array([10,12,13,16,20])

# result of the linear interp with the numpy function
np.interp(time_a, time_b, values_b)

# result of the cubic interpolation
f = interpolate.interp1d(time_b,values_b, kind="cubic")
time_a[time_a<time_b.min()]=time_b.min() # use this to stay on range define by the times of b
time_a[time_a>time_b.max()]=time_b.max() # use this to stay on range define by the times of b
f(time_a)


来源:https://stackoverflow.com/questions/42136280/interpolate-to-specific-time

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!