根据另一个熊猫中开始日期和结束日期列的条件创建新的熊猫数据框

时间:2021-04-16 23:40:45

标签: python pandas dataframe datetime

我在 Pandas 数据框中有开始日期时间和结束日期时间列,如下所示。

enter image description here

如果结束日期和时间更改为另一天或另一小时,我需要创建一个新行,开始时间为下一小时的开始时间,结束时间为该小时的结束时间(如果原始结束时间 >小时)或等于原始数据中的结束时间(如果原始结束时间 < 当前小时)和很快。得到的预期表如下所示。

enter image description here

Pandas 是否有可能,因为我的数据在数据框中

1 个答案:

答案 0 :(得分:1)

计算Start_TimeEnd_Time之间的小时差(称之为length),然后使用length将每一行重复df.reindex(df.reindex.repeat(...))次。 然后为行分配一个从 0length-1 的计数器,分别在开始日期创建的每个组中。

然后对于 Start_Time,只要计数器不为零(即这不是该日期的起始行),将时间四舍五入到 hh:00:00 并按计数器递增 hour

对于 End_Time,只要 counter 不等于 length-1(即这不是该日期的最后一行),将 End_Time 设置为 Start_Time 但分钟和第二个重置为 59,即格式为:hh:59:59 其中小时来自 Start_Time

使用:

df = (pd.DataFrame({
        'Start_Time': ['2019-08-29 17:29:29', 
              '2019-09-04 17:29:25', '2019-09-25 10:16:32'], 
        'End_Time': ['2019-08-29 17:32:18', 
              '2019-09-04 18:14:41', '2019-09-26 13:01:26']}))
df.Start_Time = pd.to_datetime(df.Start_Time)
df.End_Time = pd.to_datetime(df.End_Time)
timeDiff = df.End_Time.dt.floor(freq = 'H') - df.Start_Time.dt.floor(freq = 'H')

df['length'] = (timeDiff.dt.days * 24 + timeDiff.dt.seconds//3600 + 1)

df = df.reindex(df.index.repeat(df['length'])).reset_index(drop = True)
df['counter'] = (df.groupby(df.Start_Time.dt.date)['length']
                        .transform(lambda x: np.arange(x.iloc[0])))

mask = df.counter.eq(0)
(df.Start_Time.where(mask, df.Start_Time.dt.round('H') + 
              pd.to_timedelta(df.counter, unit = 'h'), inplace = True))


mask = df.length.eq(df.counter + 1)
masked_val = ((pd.to_timedelta(1, unit = 'h') + 
                df.Start_Time.dt.floor(freq = 'H'))
              .dt.ceil(freq = 'H') + pd.to_timedelta(-1, unit = 'S'))    

df.End_Time.where(mask, masked_val, inplace = True)
df.drop(columns = df.columns[2:], axis = 1, inplace = True)

输出:

>>> df
              Start_Time            End_Time
0  2019-08-29 17:29:29 2019-08-29 17:32:18
1  2019-09-04 17:29:25 2019-09-04 17:59:59
2  2019-09-04 18:00:00 2019-09-04 18:14:41
3  2019-09-25 10:16:32 2019-09-25 10:59:59
4  2019-09-25 11:00:00 2019-09-25 11:59:59
5  2019-09-25 12:00:00 2019-09-25 12:59:59
...
28 2019-09-26 11:00:00 2019-09-26 11:59:59
29 2019-09-26 12:00:00 2019-09-26 12:59:59
30 2019-09-26 13:00:00 2019-09-26 13:01:26