按周将每日数据的大熊猫数据框转换为每日数据的长数据框

时间:2019-05-27 02:24:11

标签: pandas

我正在使用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

欢迎使用其他方法。

1 个答案:

答案 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