【问题标题】:pandas - adding aggregated featurepandas - 添加聚合功能
【发布时间】:2020-10-07 23:00:07
【问题描述】:

我在 pandas 中有这个数据框:

   day customer  amount
0    1    cust1     500
1    2    cust2     100
2    1    cust1      50
3    2    cust1     100
4    2    cust2     250
5    6    cust1      20

我想创建一个新列“amount2days”,以便汇总过去两天每位客户的金额,以获得以下数据框:

   day customer  amount    amount2days   ----------------------------
0    1    cust1     500    500           (no past transactions)
1    2    cust2     100    100           (no past transactions)
2    1    cust1      50    550           (500 + 50 = rows 0,2 
3    2    cust1     100    650           (500 + 50 + 100, rows 0,2,3)
4    2    cust2     250    350           (100 + 250, rows 1,4) 
5    6    cust1      20    20            (notice day is 6, and no day=5 for cust1)

即我想执行以下(伪)代码:

df['amount2days'] = df_of_past_2_days['amount'].sum()

对于每一行。这样做最方便的方法是什么?

我希望对一天进行求和,但天数不一定要在每个新行中递增,如示例所示。我仍然想总结过去 2 天的金额。

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    我认为它只是在几天内滚动:

    def get_roll(x):
        s = pd.Series(x['amount'].values, 
                      index=pd.to_datetime('1900-01-01') + pd.to_timedelta(x['day'], unit='D')
                     )
        return pd.Series(s.rolling('2D').sum().values, index=x.index)
    
    df['amount2days'] = (df.groupby('customer').apply(get_roll)
                           .reset_index(level=0, drop=True)
                        )
    

    输出:

       day customer  amount  amount2days
    1    1    cust1     500        500.0
    2    1    cust2     100        100.0
    3    1    cust1      50        550.0
    4    2    cust1     100        650.0
    5    2    cust2     250        350.0
    6    3    cust1      20        120.0
    

    选项 2:由于您希望仅在两天内获得累计金额,因此今天的金额仅与前一天的金额相加。所以我们可以利用shift:

    df['amount2days'] = df.groupby(['customer','day'])['amount'].cumsum()
    
    # shift the last item of the previous day and add
    df['amount2days'] += (df.drop_duplicates(['day','customer'],keep='last')
       .groupby(['customer'])['amount2days'].shift()
       .reindex(df.index)
       .ffill()
       .fillna(0)
    )
    

    【讨论】:

    • 很遗憾不是,请注意第 4 行的总和需要为 650(第 1 天和第 2 天的总和为 500 + 50 + 100
    • day 只是数字还是datetime 类型?您可以在datetime 类型上选择rolling('2D')
    • day 只是一个数字
    • @user112112 查看使用按天滚动的修改版本的更新答案。
    猜你喜欢
    • 2021-01-21
    • 2016-06-26
    • 1970-01-01
    • 2019-01-26
    • 2015-12-10
    • 2021-09-19
    • 1970-01-01
    • 2020-02-05
    • 2019-03-10
    相关资源
    最近更新 更多