【问题标题】:Occurrence counts of values for each group as separate columns每个组的值的出现计数作为单独的列
【发布时间】:2019-05-24 03:43:58
【问题描述】:

我有一张包含近 3100 万条记录的表。 大约有 10 列,其中两列是卡号和 transaction_status。每张卡片可以有多行。所以可能有 2000 行同一张卡,每行作为具有相应状态的交易

transaction_Status 的值为“Y”/“N”。

我想使用 pandas 数据框向此表添加另外两列,“count_of_approved”、“count_of_rejected”。

我该怎么做? trn 到目前为止,我一直在使用 get_dummies() 和 merge(),但是这需要很多时间,更糟糕的是,会导致内存不足。

所以说我的输入如下:

trn_id | card_id | status
1      | c1      | Y
2      | c2      | Y
3      | c2      | N
4      | c3      | Y 
5      | c3      | Y 

我希望我的输出是

trn_id | card_id | status | num_approved | num_of_denied
1      | c1      | Y      | 1            | 0
2      | c2      | Y      | 1            | 1
3      | c2      | N      | 1            | 1
4      | c3      | Y      | 2            | 0
5      | c3      | Y      | 2            | 0

我的代码如下所示:

import pandas as panda
a = panda.DataFrame({'id':[1,2,3],'c_id':[22,22,33], 'status':['Y','Y','N']})
temp = a.status.str.get_dummies()
a[['N','Y']]= temp
tt = a.groupby(['c_id'])['Y'].count()
tt=tt.reset_index()
yes_count_added = a.merge(tt,how='right',on='c_id')
yes_count_added.rename(columns = {'Y_y':'num_of_approved'})

【问题讨论】:

    标签: python pandas dataframe group-by pandas-groupby


    【解决方案1】:

    您可以 GroupBy card_id 并使用带有 lambda 表达式的 transformsum 的次数 status 等于 Ynum_approvedNnum_of_denied使用eq:

    df['num_approved'] = df.groupby('card_id').status.transform(
                                    lambda x: x.eq('Y').sum())
    df['num_of_denied'] = df.groupby('card_id').status.transform(
                                     lambda x: x.eq('N').sum())
    
         trn_id card_id  status    num_approved    num_of_denied
    0       1      c1      Y             1              0
    1       2      c2      Y             1              1
    2       3      c2      N             1              1
    3       4      c3      Y             2              0
    4       5      c3      Y             2              0
    

    【讨论】:

    • 这很整洁。我喜欢这个解决方案。可读且直观地有意义。我需要在 3100 万条记录上尝试一下,但要检查内存不足
    【解决方案2】:

    使用str.get_dummies + 一个groupby 调用来提高性能:

    df.status.str.get_dummies().groupby(df.card_id).transform('sum')
    
       N  Y
    0  0  1
    1  1  1
    2  1  1
    3  0  2
    4  0  2
    

    v = (df.status
           .str.get_dummies()
           .groupby(df.card_id)
           .transform('sum')
           .rename({'Y': 'num_approved', 'N': 'num_denied'}, axis=1))
    
    pd.concat([df, v], axis=1)
    
       trn_id card_id status  num_denied  num_approved
    0       1      c1      Y           0             1
    1       2      c2      Y           1             1
    2       3      c2      N           1             1
    3       4      c3      Y           0             2
    4       5      c3      Y           0             2
    

    【讨论】:

      【解决方案3】:

      你可以使用crosstab:

      import pandas as pd
      
      a = pd.DataFrame(
          {'trn_id': [1, 2, 3, 4, 5],
           'card_id': ['c1', 'c2', 'c2', 'c3', 'c3'],
           'status': ['Y', 'Y', 'N', 'Y', 'Y']})
      
      crosstab = pd.crosstab(a.card_id, a.status).reset_index(level=0).rename(
          columns={'Y': 'num_approved', 'N': 'num_denied'})
      print(pd.merge(a, crosstab, on='card_id'))
      

      输出

        card_id status  trn_id  num_denied  num_approved
      0      c1      Y       1           0             1
      1      c2      Y       2           1             1
      2      c2      N       3           1             1
      3      c3      Y       4           0             2
      4      c3      Y       5           0             2
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-03-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-07-19
        • 1970-01-01
        • 1970-01-01
        • 2018-06-11
        相关资源
        最近更新 更多