【问题标题】:Pandas group by cumsum keep columnsPandas group by cumsum 保留专栏
【发布时间】:2018-11-13 13:15:57
【问题描述】:

我现在花了几个小时试图在熊猫数据框上进行“按总和累积分组”。我查看了所有 stackoverflow 的答案,令人惊讶的是,它们都不能解决我的(非常基本的)问题:

我有一个数据框:

df1 Out[8]: Name Date Amount 0 Jack 2016-01-31 10 1 Jack 2016-02-29 5 2 Jack 2016-02-29 8 3 Jill 2016-01-31 10 4 Jill 2016-02-29 5

我在尝试着

  1. 按 ['Name','Date'] 和
  2. cumsum“金额”。
  3. 就是这样。

    所以期望的输出是:

    df1 Out[10]: Name Date Cumsum 0 Jack 2016-01-31 10 1 Jack 2016-02-29 23 2 Jill 2016-01-31 10 3 Jill 2016-02-29 15

    编辑:我正在简化问题。根据当前的答案,我仍然无法获得正确的“运行中”cumsum。仔细看,我要看的是累计和“10、23、10、15”。换句话说,我想在每个连续的日期看到一个人的总累计金额。注意:如果同一个人在一个日期有两个条目,我想将它们相加,然后将它们添加到正在运行的 cumsum 中,然后才打印总和。

【问题讨论】:

    标签: pandas group-by cumsum


    【解决方案1】:

    您需要将输出分配给新列,然后通过 drop 删除 Amount 列:

    df1['Cumsum'] = df1.groupby(by=['Name','Date'])['Amount'].cumsum()
    df1 = df1.drop('Amount', axis=1)
    print (df1)
       Name        Date  Cumsum
    0  Jack  2016-01-31      10
    1  Jack  2016-02-29       5
    2  Jack  2016-02-29      13
    3  Jill  2016-01-31      10
    4  Jill  2016-02-29       5
    

    assign 的另一个解决方案:

    df1 = df1.assign(Cumsum=df1.groupby(by=['Name','Date'])['Amount'].cumsum())
             .drop('Amount', axis=1)
    print (df1)
       Name        Date  Cumsum
    0  Jack  2016-01-31      10
    1  Jack  2016-02-29       5
    2  Jack  2016-02-29      13
    3  Jill  2016-01-31      10
    4  Jill  2016-02-29       5
    

    通过评论编辑:

    首先groupbyNameDate并聚合sum,然后groupbylevelName并聚合cumsum

    df = df1.groupby(by=['Name','Date'])['Amount'].sum()
            .groupby(level='Name').cumsum().reset_index(name='Cumsum')
    print (df)
       Name        Date  Cumsum
    0  Jack  2016-01-31      10
    1  Jack  2016-02-29      23
    2  Jill  2016-01-31      10
    3  Jill  2016-02-29      15
    

    【讨论】:

    • 感谢您的回复,但是第二组应该将 Jack 的多个 2016-02-29 金额合并在一起。所以 Cumsum 必须只有四行,分别为“10、23、10、15”。不过,我会尝试使用您提供的内容,谢谢。
    【解决方案2】:

    先设置索引,再设置 groupby。

    df.set_index(['Name', 'Date']).groupby(level=[0, 1]).Amount.cumsum().reset_index()
    


    在 OP 改变了他们的问题之后,现在这是正确的答案。

    df1.groupby(
        ['Name','Date']
    )Amount.sum().groupby(
        level='Name'
    ).cumsum()
    

    这与 jezrael 提供的答案相同

    【讨论】:

    • 感谢您的回复。根据我的编辑,您的解决方案没有提供所需的输出,但我相信您提供了很好的指导。谢谢
    • 无论谁给我投反对票,请重新考虑,因为 OP 在给出答案后改变了他们的问题。我不想出现复制 jezrael 的答案,所以我只是提到它。
    • 嗨 piRSquared,我投了反对票,因为原始所需的输出(甚至在编辑之前)没有用您的代码实现 - 所以至少不是投赞成票恕我直言。但是事后看来,您确实提供了set_index,这解决了我的第二个问题,所以我会投票。再次感谢
    • 感谢您的及时回复和帮助
    • 请注意:这为我解决了 cumsum() 不包括 groupby 列的问题。那谢谢啦!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-23
    • 2018-03-05
    • 1970-01-01
    • 2023-01-15
    相关资源
    最近更新 更多