首页 > 解决方案 > 如何在 python 中将 many_days 转换为 daily?

问题描述

我有以下内容dataframe

import pandas as pd
    dt = pd.DataFrame({'start_date': ['2019-05-20', '2019-05-21', '2019-05-21'],
                       'end_date': ['2019-05-23', '2019-05-24', '2019-05-22'],
                       'reg': ['A', 'B','A'],
                       'measure': [100, 200,1000]})

我将创建一个名为“日期”的新列,该列将具有从start_date直到的值,end_date并且还有一个新列measure_dailymeasure在这些日期之间平均分布。

所以基本上,我想扩展dt行数

所以我希望最终的 df 看起来像:

   dt_f = pd.DataFrame({'date':['2019-05-20','2019-05-21','2019-05-22','2019-05-23','2019-05-21','2019-05-22','2019-05-23','2019-05-24', '2019-05-21','2019-05-22'],
                            'reg':['A','A','A','A','B','B','B','B','A','A'],
                             'measure_daily':[25,25,25,25,50,50,50,50,500,500]})

在 python 中有没有一种有效的方法来做到这一点?

标签: pythonpython-3.xpandas

解决方案


TL;博士

只要给我解决方案:

dt = dt.assign(key=dt.index)
melt = dt.melt(id_vars = ['reg', 'measure', 'key'], value_name='date').drop('variable', axis=1)

melt = pd.concat(
    [d.set_index('date').resample('d').first().ffill() for _, d in melt.groupby(['reg', 'key'], sort=False)]
).reset_index()

melt.assign(measure = melt['measure'].div(melt.groupby(['reg', 'key'], sort=False)['reg'].transform('size'))).drop('key', axis=1)

分解:

首先我们meltstartend date同一列:

dt = dt.assign(key=dt.index)
melt = dt.melt(id_vars = ['reg', 'measure', 'key'], value_name='date').drop('variable', axis=1)

  reg  measure  key       date
0   A      100    0 2019-05-20
1   B      200    1 2019-05-21
2   A     1000    2 2019-05-21
3   A      100    0 2019-05-23
4   B      200    1 2019-05-24
5   A     1000    2 2019-05-22

然后我们resample每天一边申请一边把groupby不同的人留reg在自己的群里。

melt = pd.concat(
    [d.set_index('date').resample('d').first().ffill() for _, d in melt.groupby(['reg', 'key'], sort=False)]
).reset_index()

        date reg  measure  key
0 2019-05-20   A    100.0  0.0
1 2019-05-21   A    100.0  0.0
2 2019-05-22   A    100.0  0.0
3 2019-05-23   A    100.0  0.0
4 2019-05-21   B    200.0  1.0
5 2019-05-22   B    200.0  1.0
6 2019-05-23   B    200.0  1.0
7 2019-05-24   B    200.0  1.0
8 2019-05-21   A   1000.0  2.0
9 2019-05-22   A   1000.0  2.0

最后,我们在每个组的 上展开measure列:sizeassign

melt.assign(measure = melt['measure'].div(melt.groupby(['reg', 'key'], sort=False)['reg'].transform('size'))).drop('key', axis=1)

        date reg  measure
0 2019-05-20   A     25.0
1 2019-05-21   A     25.0
2 2019-05-22   A     25.0
3 2019-05-23   A     25.0
4 2019-05-21   B     50.0
5 2019-05-22   B     50.0
6 2019-05-23   B     50.0
7 2019-05-24   B     50.0
8 2019-05-21   A    500.0
9 2019-05-22   A    500.0

推荐阅读