Python/Pandas:如何将cumsum和cumcount与agg函数相结合?

3
我有一个DataFrame,我正在按内部得分问题日期(按季度)进行分组。然后,我想创建一个统计表格,其中包括贷款数量的累积计数(由贷款编号的不同计数表示),贷款金额的累积总和以及实际损失未偿本金的总和。累积总和和累积计数应包括在该特定时间点之前的第一个日期的快照。(即Q1 2015到Q2 2015的累积总和,然后从Q1 2015到Q3 2015,然后从Q1 2015到Q4 2015等)

样本数据集:

   Loan #   Amount Issue Date TU Status List Internal Score  Last Actual Paid  \
0   57144  3337.76 2017-04-03              B              A               0.0   
1   57145  5536.46 2017-04-03              B              C               0.0   
2   57160  3443.91 2017-04-03              B              B               0.0   
3   57161  1162.79 2017-04-03              B              B               0.0   
4   57162  3845.98 2017-04-03              B              B               0.0   
5   57163  3441.50 2017-04-03              B              B               0.0   
6   57164  2039.96 2017-04-03              B              C               0.0   
7   57165  4427.53 2017-04-03              B              A               0.0   
8   57166  4427.53 2017-04-03              B              A               0.0   
9   57167  1617.77 2017-04-03              B              B               0.0   

   Outstanding-Principal  Actual Loss  
0                3337.76          0.0  
1                5536.46          0.0  
2                3443.91          0.0  
3                1162.79          0.0  
4                3845.98          0.0  
5                3441.50          0.0  
6                2039.96          0.0  
7                4427.53          0.0  
8                4427.53          0.0  
9                1617.77          0.0

我尝试了以下的方法:
container = []
for i in ['A', 'B', 'C', 'D']:

    subdf = df[df['Internal Score'].str.contains(i)]

    # Calculate Quarterly Vintages
    subdf.set_index('Issue Date', inplace=True)
    df2 = subdf.groupby(pd.TimeGrouper('Q')).agg({'Outstanding-Principal': np.sum, 'Actual Loss': np.sum,
                                                  'Amount': cumsum, 'Loan #': cumcount})
    df2['Internal Score'] = i
    container.append(df2)

ddf = pd.concat(container)

“累计贷款数量(由贷款编号的不同计数表示)”是什么意思?结果会是什么样子? - pansen
通常我会在agg函数中创建一个字典,例如.agg('Loan #': len}。但这只是每个季度的计数。我想要累积计数。 - Riley Hun
明白了。您处理的时间跨度是否超过一年?比如从2015年第一季度到2017年第三季度,还是仅限于每年内的滚动时间? - pansen
已经超过一年了。我的当前数据跨越从2015年第四季度到2017年第一季度。 - Riley Hun
你会在整个时间跨度内累积还是仅在年份内累积? - pansen
整个时间跨度,而不仅仅是在一年内。 - Riley Hun
1个回答

2
你可以先使用 groupby,然后再应用 cumsum。我修改了你的虚拟数据,将日期跨越了四分之一,以便更清楚地说明你的示例:
print(df)

    Loan #  Amount      Issue Date  Internal Score  Outstanding Principal   Actual Loss
0   57144   3337.76     2017-04-03  A               3337.76                 0.0
1   57145   5536.46     2017-04-03  C               5536.46                 0.0
2   57160   3443.91     2017-04-03  B               3443.91                 0.0
3   57161   1162.79     2017-04-03  B               1162.79                 0.0
4   57162   3845.98     2017-04-03  B               3845.98                 0.0
5   57163   3441.50     2017-07-03  B               3441.50                 0.0
6   57164   2039.96     2017-07-03  C               2039.96                 0.0
7   57165   4427.53     2017-07-03  A               4427.53                 0.0
8   57166   4427.53     2017-07-03  A               4427.53                 0.0
9   57167   1617.77     2017-07-03  B               1617.77                 0.0

首先,创建一个包含标识给定时间戳的季度和年份的键的列:
# in case it is not a timestamp already
df["Issue Date"] = pd.to_datetime(df["Issue Date"])

dt = df["Issue Date"].dt
df["Quarter"] = dt.strftime("%Y").str.cat(dt.quarter.astype(str), " Q")

print(df["Quarter"])

0    2017 Q2
1    2017 Q2
2    2017 Q2
3    2017 Q2
4    2017 Q2
5    2017 Q3
6    2017 Q3
7    2017 Q3
8    2017 Q3
9    2017 Q3
Name: Quarter, dtype: object

现在,聚合:
funcs = {'Outstanding Principal': np.sum, 
         'Actual Loss': np.sum, 
         'Amount': np.sum, 
         'Loan #': len}

result = df.groupby(['Internal Score', "Quarter"]).agg(funcs)
print(result)

                            Outstanding Principal   Amount      Actual Loss     Loan #
Internal Score  Quarter                 
             A  2017 Q2     3337.76                 3337.76     0.0             1
                2017 Q3     8855.06                 8855.06     0.0             2
             B  2017 Q2     8452.68                 8452.68     0.0             3
                2017 Q3     5059.27                 5059.27     0.0             2
             C  2017 Q2     5536.46                 5536.46     0.0             1
                2017 Q3     2039.96                 2039.96     0.0             1

最后使用cumsumtransform

cum_cols = ["Amount", "Loan #"]
cumsums = result.groupby(level="Internal Score")[cum_cols].transform(lambda x: x.cumsum())
result.loc[:, cum_cols] = cumsums

print(result)
                            Outstanding Principal   Amount      Actual Loss     Loan #
Internal Score  Quarter                 
             A  2017 Q2     3337.76                 3337.76     0.0             1
                2017 Q3     8855.06                12192.82     0.0             3
             B  2017 Q2     8452.68                 8452.68     0.0             3
                2017 Q3     5059.27                13511.95     0.0             5
             C  2017 Q2     5536.46                 5536.46     0.0             1
                2017 Q3     2039.96                 7576.42     0.0             2

太棒了!非常感谢pansen。非常感激。 - Riley Hun
很高兴能帮助到你 :-) - pansen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接