【问题标题】:interpolate to specific time插值到特定时间
【发布时间】:2017-02-09 20:29:52
【问题描述】:

假设我有这个代码:

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),
              ])

所以,我有 5 个来自 a 的测量值和 2 个来自 b 的测量值。

我想通过使用a 作为基础,在a 发生的特定时间找到缺失的b 值。

所以,最终的b 将始终具有a 的时间值和长度。(当时,我想以time.mktime(datetime.strptime(s, "%d-%m-%Y %H:%M:%S.%f").timetuple()) 为单位返回时间

所以,b 将是:

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)])

现在,我不知道该如何处理。

一个想法是首先执行interpas here并将b长度拉伸到与a相等。

或者使用interp1d(更灵活):

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))

那么,时间怎么处理呢?

【问题讨论】:

  • 谢谢,你的问题现在很清楚了:)

标签: python numpy scipy interpolation


【解决方案1】:

这是您问题的解决方案:

  • 首先,如果使用三次插值,则 a 至少需要 4 个值,b 需要至少 4 个值(scipy.interpolate.interp1dkind="cubic" 否则不起作用)
  • 其次,您不能使用scipy.interpolate.interp1d 插入不在您定义的范围内的值(b 次的范围)

我更改了一些您的初始代码以向您展示:

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)

【讨论】:

  • 我会在一个小时左右检查它,谢谢!(同时我不明白time_a[time_a&lt;time_b.min()]=time_b.min() # use this to stay on range define by the times of b
  • @George 在这种特殊情况下不需要带有min 函数的行,但我写它是为了有一个更通用的示例。它只是将time_a 的值设置为低于 b 的最小时间到 b 的最小时间。例如,time_a = [0,1,2,3,4,5]b_time = [3,5] 将返回 [3,3,3,3,4,5]。因此,您的插值范围与time_b 的范围相同
  • 好的,我明白了。但这仅适用于scipy interp1d 案例。此外,我在docs 中看到If xp is not increasing, the results are nonsense。但同时在args 中它说Otherwise, xp is internally sorted after normalizing the periodic boundaries with xp = xp % period. .感谢您的解决方案! (赞成)。很明显!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-06-26
  • 2019-05-22
  • 1970-01-01
  • 1970-01-01
  • 2019-06-23
  • 1970-01-01
  • 2021-06-30
相关资源
最近更新 更多