我正在使用一个数据集,其中包含有关在某些时间范围内发生的现象的信息。系统会为我提供事件的开始和结束时间及其严重性,以及其他一些信息。我想通过在设置的时间段内扩展行并将其余信息保留为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
达到这种结果的有效方法是什么?
答案 0 :(得分:5)
假设您使用的是熊猫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)
答案 1 :(得分:1)
一种方法是使用pd.date_range重新建立数据名的索引,使用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