繁体   English   中英

将 function 应用于每一行,其中 function 使用 DataFrame 的所有先前行

[英]Apply a function to each row, where the function uses all previous rows of the 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

它按datecustomer_idtransaction_id排序。

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

      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

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

我相信您首先需要过滤fraud列的1值,然后通过GroupBy.agg聚合计数和sum ,然后为每个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  

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM