DateTime范围为“长格式”,间隔时间为15分钟(“钟点”)。

时间:2020-09-18 10:37:23

标签: python pandas time-series

假设我有以下熊猫DataFrame:

(see code below to re-create this example)

    user    starttime   endtime     flag
0   Alice   2020-03-20 15:05:00     2020-03-20 15:36:00     y
1   Bob     2020-03-20 15:16:00     2020-03-20 15:40:00     m
2   Chap    2020-03-20 15:00:00     2020-03-20 15:30:00     y
3   Dana    2020-03-20 20:05:00     2020-03-20 20:44:00     y

我想将每个时间范围(即starttimeendtime之间的时间划分为15分钟的时间段(例如this),但是我想精确地将15分钟的时间段(即“ o”时钟季度”(例如15:00、15:15)以及与每个季度相对应的持续时间。

基本上,数据将如下所示:

    name    flag    quarter                 duration
0   Alice   y       2020-03-20 15:00:00     00:10:00
1   Alice   y       2020-03-20 15:15:00     00:15:00
2   Alice   y       2020-03-20 15:30:00     00:05:00
3   Bob     m       2020-03-20 15:15:00     00:14:00
4   Bob     m       2020-03-20 15:30:00     00:01:00
5   Chap    y       2020-03-20 15:00:00     00:15:00
6   Chap    y       2020-03-20 15:15:00     00:15:00
7   Chap    y       2020-03-20 15:30:00     00:00:00
8   Dana    y       2020-03-20 20:00:00     00:10:00
9   Dana    y       2020-03-20 20:15:00     00:15:00
10  Dana    y       2020-03-20 20:30:00     00:05:00

如果您想知道 是什么 :我还有另一个数据框,其价格与“钟点价格”相关联,因此,我需要计算在合并数据之前的每个季度。


代码以重新创建示例

import pandas as pd
df = pd.DataFrame({
    'user': ['Alice', 'Bob', 'Chap', 'Dana'],
    'starttime': ['2020-03-20 15:05:00', '2020-03-20 15:16:00','2020-03-20 15:00:00', '2020-03-20 20:05:00' ],
    'endtime': ['2020-03-20 15:36:00', '2020-03-20 15:40:00','2020-03-20 15:30:00', '2020-03-20 20:44:00'],
    'flag': ['y','m','y', 'y']
})

df['starttime'] = pd.to_datetime(df['starttime'])
df['endtime'] = pd.to_datetime(df['endtime'])

1 个答案:

答案 0 :(得分:0)

我想出了自己的解决方案,

# Split into quarters
new = pd.DataFrame(((
                        e.name, 
                        e.flag, 
                        # for the first interval use the starttime
                        e.starttime if date == e.starttime.floor('15min') else date,
                        # for the last interval use the endtime
                        e.endtime if date == e.endtime.floor('15min') else date + pd.Timedelta(minutes=15)
                    )    
                    #iterate over thet uples
                    for e  in df.itertuples()
                    # iterate for each range date
                    for date in pd.date_range(e.starttime.floor('15min'), e.endtime.floor('15min'), freq='15min')
                ), columns = ['name', 'flag', 'start', 'end'])

# calculate the duration
new['duration'] = new['end']- new['start']

但是,它并不完美,我需要在可能导致错误的过程中修复很多细节。这似乎是一个典型的用例,所以我相信那里应该有更好的解决方案。

最终结果

我的最终数据集看起来像这样。我可以重用其中的一些专栏,但我认为这种方法很明显可以反映出为解决该问题而采取的步骤。

    name   flag start                   end                     duration
0   Alice   y   2020-03-20 15:05:00     2020-03-20 15:15:00     00:10:00
1   Alice   y   2020-03-20 15:15:00     2020-03-20 15:30:00     00:15:00
2   Alice   y   2020-03-20 15:30:00     2020-03-20 15:41:00     00:11:00
3   Bob     m   2020-03-20 15:16:00     2020-03-20 15:30:00     00:14:00
4   Bob     m   2020-03-20 15:30:00     2020-03-20 15:40:00     00:10:00
5   Chap    y   2019-03-20 12:58:00     2019-03-20 13:00:00     00:02:00
6   Chap    y   2019-03-20 13:00:00     2019-03-20 13:15:00     00:15:00
7   Chap    y   2019-03-20 13:15:00     2019-03-20 13:30:00     00:15:00
8   Chap    y   2019-03-20 13:30:00     2019-03-20 13:41:00     00:11:00
9   Dana    y   2020-03-20 20:05:00     2020-03-20 20:15:00     00:10:00
10  Dana    y   2020-03-20 20:15:00     2020-03-20 20:30:00     00:15:00
11  Dana    y   2020-03-20 20:30:00     2020-03-20 20:44:00     00:14:00