对每一行应用一个函数,其中函数使用 DataFrame 的所有先前行

Posted

技术标签:

【中文标题】对每一行应用一个函数,其中函数使用 DataFrame 的所有先前行【英文标题】:Apply a function to each row, where the function uses all previous rows of the DataFrame 【发布时间】:2020-08-19 21:06:25 【问题描述】:

我有一个类似于以下格式的 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 会一样,但是是交易金额的累计,而不是计数。

      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() 将其应用于每一行?

【问题讨论】:

过滤出日期为 customer_id 和 aggregate 上应用 groupby 并在列 fraudamount 上使用函数 cumsum 你的价值观正确吗?根据您的逻辑,第 3 行的数量应该是 25 而不是 0? 否,因为它应该只计算以前的值 fraud == 1 【参考方案1】:

我相信您首先需要过滤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  

【讨论】:

我的和你的差不多。但还没有完成。所以,投票给你并删除我的。

以上是关于对每一行应用一个函数,其中函数使用 DataFrame 的所有先前行的主要内容,如果未能解决你的问题,请参考以下文章

Oracle 函数

表格中对每一行进行编辑

oracle常用函数介绍

oracle常用函数详解(详细)

OracleOracle中常用函数大全

oracle常用函数详解(详细)