我正在使用pandas数据框,其中每一行都包括该周的开始日期以及该周的每日数据。例如:
start_date mon tue wed thu fri sat sun
2017-01-01 10 15 8 19 20 21 4
我想进行时间序列分析,并且需要以下格式的数据:
date amount
2017-01-01 10
2017-01-02 15
2017-01-03 8
2017-01-04 19
2017-01-05 20
2017-01-06 21
2017-01-07 4
我相信我可以使用pandasmelt将数据集从宽转换为长,但是我在如何最好地填写日期方面苦苦挣扎。
我尝试了以下方法,但似乎可以解决此问题:
df = pd.DataFrame({'start_date': {0: '2017-01-01'}, 'mon': {0: 10},
'tue': {0: 15}, 'wed': {0: 8}, 'thu': {0: '19'},
'fri': {0: 20}, 'sat': {0: 21}, 'sun': {0: 4}})
df = df.melt(id_vars='start_date', value_name="amount")
day_add = {'mon': 0,
'tue': 1,
'wed': 2,
'thu': 3,
'fri': 4,
'sat': 5,
'sun': 6,
}
df = df.replace({"variable": day_add})
df['date'] = pd.to_datetime(df['start_date'], infer_datetime_format=True) +
pd.to_timedelta(df['variable'], unit='d')
print(df[['date', 'amount']].sort_values(by=['date']))
当前代码的结果:
date amount
1 2017-01-01 10
5 2017-01-02 15
6 2017-01-03 8
4 2017-01-04 19
0 2017-01-05 20
2 2017-01-06 21
3 2017-01-07 4
欢迎使用其他方法。
答案 0 :(得分:2)
您的解决方案非常好。我唯一可能要更改的是将replace
调用替换为可以在线执行的快速{er)map
调用。
为完整起见,这是使用stack
的类似解决方案。这几乎与使用melt
相同。我还展示了如何在这里使用map
:
u = df.set_index('start_date').stack()
u.index = (
pd.to_datetime(u.index.get_level_values(0))
+ pd.to_timedelta(u.index.get_level_values(1).map(day_add), unit='d'))
u.rename_axis('date').reset_index(name='amount')
date amount
0 2017-01-01 10
1 2017-01-02 15
2 2017-01-03 8
3 2017-01-04 19
4 2017-01-05 20
5 2017-01-06 21
6 2017-01-07 4