【问题标题】:pandas calculate scores for each group based on multiple functionspandas 根据多个函数计算每组的分数
【发布时间】:2018-11-09 10:34:29
【问题描述】:

我有以下df

group_id    code    amount    date
   1        100      20       2017-10-01
   1        100      25       2017-10-02
   1        100      40       2017-10-03
   1        100      25       2017-10-03
   2        101      5        2017-11-01
   2        102      15       2017-10-15
   2        103      20       2017-11-05

我喜欢groupbygroup_id,然后根据以下特征计算每个组的分数:

  1. 如果code在一个组中的值都相同,则得分0,否则得分10;
  2. 如果amount总和> 100,则得分20,否则得分0;
  3. sort_values by date 按降序对日期之间的差异求和,如果总和

所以结果 df 看起来像,

group_id    code    amount    date          score
   1        100      20       2017-10-01     50
   1        100      25       2017-10-02     50
   1        100      40       2017-10-03     50
   1        100      25       2017-10-03     50
   2        101      5        2017-11-01     10
   2        102      15       2017-10-15     10
   2        103      20       2017-11-05     10

以下是与上述每个功能相对应的功能:

def amount_score(df, amount_col, thold=100):
    if df[amount_col].sum() > thold:
        return 20
    else:
        return 0

def col_uniq_score(df, col_name):
    if df[col_name].nunique() == 1:
        return 0
    else:
        return 10

def date_diff_score(df, col_name):
    df.sort_values(by=[col_name], ascending=False, inplace=True)
    if df[col_name].diff().dropna().sum() / np.timedelta64(1, 'D') < 5:
        return score + 30
    else:
        return score

我想知道如何将这些函数应用于每个组并计算所有函数的总和以给出score

【问题讨论】:

    标签: python-3.x pandas dataframe pandas-groupby


    【解决方案1】:

    您可以尝试groupby.transform 与原始DataFrame 相同大小的Seriesnumpy.whereif-elseSeries

    grouped = df.sort_values('date', ascending=False).groupby('group_id', sort=False)
    
    a = np.where(grouped['code'].transform('nunique') == 1, 0, 10)
    print (a)
    [10 10 10  0  0  0  0]
    
    b = np.where(grouped['amount'].transform('sum') > 100, 20, 0)
    print (b)
    [ 0  0  0 20 20 20 20]
    
    c = np.where(grouped['date'].transform(lambda x:x.diff().dropna().sum()).dt.days < 5, 30, 0)
    print (c)
    [30 30 30 30 30 30 30]
    
    df['score'] =  a + b + c
    print (df)
    
       group_id  code  amount       date  score
    0         1   100      20 2017-10-01     40
    1         1   100      25 2017-10-02     40
    2         1   100      40 2017-10-03     40
    3         1   100      25 2017-10-03     50
    4         2   101       5 2017-11-01     50
    5         2   102      15 2017-10-15     50
    6         2   103      20 2017-11-05     50
    

    【讨论】:

    • 您可以以grouped = df.sort_values('date', ascending=False).groupby('group_id') 为起点,然后在大多数情况下使用grouped...
    猜你喜欢
    • 2020-09-21
    • 1970-01-01
    • 1970-01-01
    • 2020-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-11
    相关资源
    最近更新 更多