如何使用多索引逐行计算百分比

时间:2019-08-09 03:07:36

标签: pandas

我有大约3000万行的数据框:

ID         DATE                         STATUS      

123        2017-01-04 18:08:56+00:00    True        
           2017-01-04 18:09:56+00:00    True        
           2017-01-06 19:12:30+00:00    False       
           2017-01-07 19:12:30+00:00    False       
           2017-01-08 19:12:30+00:00    False       

401        2017-01-01 18:08:56+00:00    False       
           2017-01-02 18:19:56+00:00    True        
           2017-01-05 09:15:30+00:00    True        
           2017-01-06 12:12:30+00:00    False       

我想逐行计算每个ID的True值的百分比。该值应根据当前行的状态增加或减少。

我很难描述,但结果应该看起来像这样:

ID         DATE                         STATUS      VALUE(%)

123        2017-01-04 18:08:56+00:00    True        100
           2017-01-04 18:09:56+00:00    True        100
           2017-01-06 19:12:30+00:00    False       66.66
           2017-01-06 19:12:30+00:00    False       50
           2017-01-06 19:12:30+00:00    False       40

401        2017-01-04 18:08:56+00:00    False       0
           2017-01-04 18:09:56+00:00    True        50
           2017-01-06 19:12:30+00:00    True        66.66
           2017-01-06 19:12:30+00:00    False       50       

2 个答案:

答案 0 :(得分:1)

GroupBy.cumsum除以GroupBy.cumcount,再乘以100,并在必要时舍入:

a = df.groupby(level=0)['STATUS'].cumsum()
b = df.groupby(level=0).cumcount() + 1

df['Val'] = a.div(b).mul(100).round(2)

print (df)
                               STATUS     Val
ID  DATE                                     
123 2017-01-04 18:08:56+00:00    True  100.00
    2017-01-04 18:09:56+00:00    True  100.00
    2017-01-06 19:12:30+00:00   False   66.67
    2017-01-07 19:12:30+00:00   False   50.00
    2017-01-08 19:12:30+00:00   False   40.00
401 2017-01-01 18:08:56+00:00   False    0.00
    2017-01-02 18:19:56+00:00    True   50.00
    2017-01-05 09:15:30+00:00    True   66.67
    2017-01-06 12:12:30+00:00   False   50.00

答案 1 :(得分:1)

您也可以这样做

df['p'] = df.groupby('ID')['STATUS'].transform(lambda x: x.cumsum()/(x.index-x.index.min()+1)).mul(100)