代码之家  ›  专栏  ›  技术社区  ›  daiyue

pandas基于多个函数计算每组的分数

  •  0
  • daiyue  · 技术社区  · 7 年前

    我有以下的 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
    

    我喜欢 groupby group_id 然后根据以下特征计算每组的分数:

    1. 如果 code 一组数值相同,否则得0分和10分;
    2. 如果 amount 总和为100,否则为20分和0分;
    3. sort_values 通过 date 按降序排列并对日期之间的差异求和,如果求和<5,则得分30,否则为0。

    所以结果 东风 看起来像,

    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 .

    1 回复  |  直到 7 年前
        1
  •  1
  •   jezrael    7 年前

    你可以试试 groupby.transform 同样大小的 Series 原汁原味 DataFrame 具有 numpy.where 对于 if-else 对于 系列 :

    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