首页 > 解决方案 > 对每一行应用一个函数,其中函数使用 DataFrame 的所有先前行

问题描述

我有一个格式类似于以下的 DataFrame:

      date     customer_id    transaction_id    amount    fraud
2020-01-01               1                10        25        0
2020-01-01               2                11        14        1
2020-01-02               1                12        48        1
2020-01-02               2                13        12        1
2020-01-02               2                14        48        1
2020-01-03               1                15        30        0

它按date, customer_id,排序transaction_id

我现在想创建两个新列,fraud_count它们将显示fraud == 1该客户在当前日期(但不包括当前日期)进行的欺诈 ( ) 交易的数量。fraud_sum将是相同的,但交易金额的累计,而不是计数。

      date     customer_id    transaction_id    amount    fraud    fraud_count    fraud_sum  
2020-01-01               1                10        25        0              0            0
2020-01-01               2                11        14        1              0            0
2020-01-02               1                12        48        1              0            0
2020-01-02               2                13        12        1              1           14
2020-01-02               2                14        41        1              1           14
2020-01-03               1                15        30        0              1           48
2020-01-03               2                16        88        0              3           67

我怎样才能做到这一点?是否可以创建一个查看整个 DataFrame 或当前行之前的所有行的函数,然后使用 将其应用于每一行pd.DataFrame.apply()

标签: pythonpandasapplyaggregate-functions

解决方案


我相信你需要首先过滤列1的值fraud,然后聚合计数和sumby GroupBy.agg,然后创建累积总和customer_id并添加下几天以不匹配以前的:

df1 = df[df['fraud'].eq(1)].copy()
df1 = (df1.groupby(['customer_id', 'date'])
          .agg(fraud_count=('amount','size'),
               fraud_sum=('amount','sum'))
          .reset_index())
cols = ['fraud_sum','fraud_count']
df1[cols] = df1.groupby('customer_id')[cols].cumsum()
df1['date'] += pd.Timedelta(1, 'day')

最后使用DataFrame.merge替换缺失值:

df = df.merge(df1[['fraud_count','fraud_sum', 'date','customer_id']], 
              on=['date','customer_id'], how='left')

df[cols] = df[cols].fillna(0).astype(int)
print (df)
        date  customer_id  transaction_id  amount  fraud  fraud_count  \
0 2020-01-01            1              10      25      0            0   
1 2020-01-01            2              11      14      1            0   
2 2020-01-02            1              12      48      1            0   
3 2020-01-02            2              13      12      1            1   
4 2020-01-02            2              14      41      1            1   
5 2020-01-03            1              15      30      0            1   
6 2020-01-03            2              16      88      0            3   

   fraud_sum  
0          0  
1          0  
2          0  
3         14  
4         14  
5         48  
6         67  

推荐阅读