在Pandas中按日期范围扩展行,其开始和结束时间。

10

我正在处理一组包含某些时间段内现象信息的数据集。我已知事件的开始和结束时间以及其严重程度,以及其他一些信息。我想通过在设定的时间段内扩展行来扩展这些时间范围,并将其余信息保留为NaN。

数据集示例:

                         date_end         severity   category
     date_start           
2018-01-04 07:00:00  2018-01-04 10:00:00     12          1
2018-01-04 12:00:00  2018-01-04 13:00:00     44          2

我的要求是:

                     severity   category
     date_start           
2018-01-04 07:00:00     12         1
2018-01-04 08:00:00     12         1
2018-01-04 09:00:00     12         1
2018-01-04 10:00:00     12         1
2018-01-04 11:00:00     nan       nan
2018-01-04 12:00:00     44         2
2018-01-04 13:00:00     44         2
2018-01-04 14:00:00     nan       nan
2018-01-04 15:00:00     nan       nan

如何高效地实现这样的结果?


你是如何确定 date_start 范围的结束日期的? - Scott Boston
它可以是任意的,可以工作为: datetime.datetime.now() - Aleks-1and
第一行的end_date应该是10:00而不是7:00,符合预期输出吗?第二行的date_start应该是2018-01-04而不是2018-01-05吗? - Scott Boston
1
是的,说得好,我在格式方面犯了一个错误。 - Aleks-1and
1
第二个日期开始是2018-01-04 12:00:00,而不是2018-01-05 12:00:00 - pythonic833
显示剩余2条评论
2个回答

10

假设您正在使用pandas v0.25,请使用explode

df['hour'] = df.apply(lambda row: pd.date_range(row.name, row['date_end'], freq='H'), axis=1)
df = df.explode('hour').reset_index() \
        .drop(columns=['date_start', 'date_end']) \
        .rename(columns={'hour': 'date_start'}) \
        .set_index('date_start')

对于具有 nan 的行,您可以重新索引您的数据框。

# Report from Jan 4 - 5, 2018, from 7AM - 7PM
days = pd.date_range('2018-01-04', '2018-01-05')
hours = pd.to_timedelta(range(7, 20), unit='h')
tmp = pd.MultiIndex.from_product([days, hours], names=['Date', 'Hour']).to_frame()

s = tmp['Date'] + tmp['Hour']
df.reindex(s)

关于重新索引的问题,我使用了以下代码:df.reindex(date_range, fill_value=np.NaN)``` 在将date_start设为最小值,date_end设为任意值之前。 你认为哪种解决方案更好? - Aleks-1and
你的解决方案报告了一天中的所有24个小时。我的答案只报告早上7点到晚上7点之间的时间。两者都能很好地工作,但是用途略有不同。 - Code Different
感谢您的澄清!还有抱歉格式不好,我还在努力理解。 - Aleks-1and

3

一种方法是使用pd.date_range重新索引datafame,然后使用ffill,在索引大于date_end的值处进行掩码处理。

df.index = pd.to_datetime(df.index)

df['date_end'] = pd.to_datetime(df['date_end'])

df1 = df.reindex(pd.date_range(df.index.min(), '2018-01-04 15:00:00', freq='H'))

df1 = df1.ffill()

df1.loc[(df1.index - df1['date_end']) > pd.Timedelta(days=0)] = np.nan

df_out = df1.drop('date_end', axis=1)

print(df_out)

输出:

                     severity  category
2018-01-04 07:00:00      12.0       1.0
2018-01-04 08:00:00      12.0       1.0
2018-01-04 09:00:00      12.0       1.0
2018-01-04 10:00:00      12.0       1.0
2018-01-04 11:00:00       NaN       NaN
2018-01-04 12:00:00      44.0       2.0
2018-01-04 13:00:00      44.0       2.0
2018-01-04 14:00:00       NaN       NaN
2018-01-04 15:00:00       NaN       NaN

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接