按在 Pandas 中开始和结束的日期范围扩展行
Posted
技术标签:
【中文标题】按在 Pandas 中开始和结束的日期范围扩展行【英文标题】:Expand rows by date range having start and end in Pandas 【发布时间】:2019-12-22 19:59:54 【问题描述】:我正在处理一个数据集,其中包含有关在某些时间范围内发生的现象的信息。我得到了事件的开始和结束时间及其严重性,以及一些其他信息。我想通过在设定的时间段内扩展行并将其余信息保留为 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 范围的结束的? 这将是任意的,可以作为:datetime.datetime.now()
第一行的 end_date 是否应该是 10:00 而不是 7:00 每个预期输出?第二行的 date_start 应该是 2018-01-04 而不是 2018-01-05?
是的,很好,我在格式化方面犯了一个错误
第二个 date_start 是 2018-01-04 12:00:00
而不是 2018-01-05 12:00:00
【参考方案1】:
假设您使用的是 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)
【讨论】:
关于重新索引的问题我使用了:date_range = pd.date_range(start=date_start, end=date_end, freq='H') df.reindex(date_range, fill_value=np.NaN)
,然后将 date_start 设置为 date_start 的最小值,并将 date_end 设置为任意值,您认为哪种解决方案效果更好
您的解决方案全天 24 小时提供报告。我的回答只在早上 7 点到晚上 7 点之间报告。两者都同样有效,但用途略有不同。
感谢您的澄清!格式也很抱歉,我还在努力解决【参考方案2】:
一种方法是使用 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
【讨论】:
以上是关于按在 Pandas 中开始和结束的日期范围扩展行的主要内容,如果未能解决你的问题,请参考以下文章