如果日期间隔大于N秒,请使用最后一个值填充列表

时间:2018-10-09 18:54:47

标签: python pandas datetime

假设我有列表data

import numpy as np
import datetime

np.random.seed(0)
aux = [10,30,50,60,70,110,120]
base = datetime.datetime(2018, 1, 1, 22, 34, 20)
data = [[base + datetime.timedelta(seconds=s), 
         round(np.random.rand(),3)] for s in aux]

这将返回:

data == 

[[datetime.datetime(2018, 1, 1, 22, 34, 30), 0.549],
 [datetime.datetime(2018, 1, 1, 22, 34, 50), 0.715],
 [datetime.datetime(2018, 1, 1, 22, 35, 10), 0.603],
 [datetime.datetime(2018, 1, 1, 22, 35, 20), 0.545],
 [datetime.datetime(2018, 1, 1, 22, 35, 30), 0.424],
 [datetime.datetime(2018, 1, 1, 22, 36, 10), 0.646],
 [datetime.datetime(2018, 1, 1, 22, 36, 20), 0.438]]

我想做的是使用最后一个上一个值填充日期之间的间隔大于10秒的空格。对于此示例,输出应为:

desired_output ==

[[datetime.datetime(2018, 1, 1, 22, 34, 30), 0.549],
 [datetime.datetime(2018, 1, 1, 22, 34, 40), 0.549],
 [datetime.datetime(2018, 1, 1, 22, 34, 50), 0.715],
 [datetime.datetime(2018, 1, 1, 22, 35), 0.715],
 [datetime.datetime(2018, 1, 1, 22, 35, 10), 0.603],
 [datetime.datetime(2018, 1, 1, 22, 35, 20), 0.545],
 [datetime.datetime(2018, 1, 1, 22, 35, 30), 0.424],
 [datetime.datetime(2018, 1, 1, 22, 35, 40), 0.424],
 [datetime.datetime(2018, 1, 1, 22, 35, 50), 0.424],
 [datetime.datetime(2018, 1, 1, 22, 36), 0.424],
 [datetime.datetime(2018, 1, 1, 22, 36, 10), 0.646],
 [datetime.datetime(2018, 1, 1, 22, 36, 20), 0.438]]

我想不出什么聪明的方法来做到这一点。 所有日期都以10秒的倍数分隔。有什么想法吗?

1 个答案:

答案 0 :(得分:2)

选项1:配熊猫

如果您愿意使用Pandas,它将使重新索引操作变得如此简单:

var

>>> import pandas as pd >>> df = pd.DataFrame(data, columns=['date', 'value']) >>> ridx = df.set_index('date').asfreq('10s').ffill().reset_index() >>> ridx date value 0 2018-01-01 22:34:30 0.549 1 2018-01-01 22:34:40 0.549 2 2018-01-01 22:34:50 0.715 3 2018-01-01 22:35:00 0.715 4 2018-01-01 22:35:10 0.603 5 2018-01-01 22:35:20 0.545 6 2018-01-01 22:35:30 0.424 7 2018-01-01 22:35:40 0.424 8 2018-01-01 22:35:50 0.424 9 2018-01-01 22:36:00 0.424 10 2018-01-01 22:36:10 0.646 11 2018-01-01 22:36:20 0.438 将填补缺少的10秒间隔。 .asfreq('10s')表示“前填充”缺少的值以及最后看到的有效值。

回到现在的数据结构(尽管请注意,元素将为2元组,而不是长度为2的列表):

.ffill()

确认:

>>> native_ridx = list(zip(ridx['date'].dt.to_pydatetime().tolist(), ridx['value']))
>>> from pprint import pprint
>>> pprint(native_ridx[:5])
[(datetime.datetime(2018, 1, 1, 22, 34, 30), 0.549),
 (datetime.datetime(2018, 1, 1, 22, 34, 40), 0.549),
 (datetime.datetime(2018, 1, 1, 22, 34, 50), 0.715),
 (datetime.datetime(2018, 1, 1, 22, 35), 0.715),
 (datetime.datetime(2018, 1, 1, 22, 35, 10), 0.603)]

选项2:原生Python

>>> assert all(tuple(i) == j for i, j in zip(desired_output, native_ridx))

示例:

import datetime

def make_daterange(
    start: datetime.datetime,
    end: datetime.datetime,
    incr=datetime.timedelta(seconds=10)
):
    yield start
    while start < end:
        start += incr
        yield start

def reindex_ffill(data: list, incr=datetime.timedelta(seconds=10)):
    dates, _ = zip(*data)
    data = dict(data)
    start, end = min(dates), max(dates)
    daterng = make_daterange(start, end, incr)
    # If initial value is not valid, the element at [0][0] will be NaN
    lastvalid = np.nan
    get = data.get
    for date in daterng:
        value = get(date)
        if value:
            yield date, value
            lastvalid = value
        else:
            yield date, lastvalid