Applying a function to each of the groups in groupby

I would like to apply a function to each of the groups in my .groupby result. My original df looks like this:

Id  Cust_type   DPP
1   A           Detractor
2   B           Detractor
3   C           Detractor
4   D           Promoter
5   A           Promoter
6   B           Passive
7   B           Detractor
8   C           Detractor
9   D           Detractor
10  D           Promoter
11  A           Promoter
12  A           Passive

I would like to calculate a score for each of the Cust_types. A score for the full df is calculated like this:

((len(df[df['DPP']=='Promoters'])-len(df[df['DPP']=='Detractors']))/(len(df)))*100

So I am trying to define a function and then apply it to each of the groups, but the below is not working because I don’t really know how to do it.

def score(x):
    return ((len(x[x['DPP']=='Promoters'])-len(x[x['DPP']=='Detractors']))/(len(x)))*100

df.groupby('Cust_type').apply(score, x))

Any help appreciated.

>Solution :

You have many syntax errors in your code.

Here is a slightly simplified version:

def score(x):
    return (x['DPP'].eq('Promoter').sum()-x['DPP'].eq('Detractor').sum())/len(x)*100

df.groupby('Cust_type').apply(score)

Or, as you use only a single column:

def score(x):
    return (x.eq('Promoter').sum()-x.eq('Detractor').sum())/len(x)*100

df.groupby('Cust_type')['DPP'].apply(score)

output:

Cust_type
A     25.000000
B    -66.666667
C   -100.000000
D     33.333333
Name: DPP, dtype: float64

Another approach:

d = {'Promoter': 1, 'Detractor': -1}

df['DPP'].map(d).fillna(0).groupby(df['Cust_type']).mean().mul(100)

Leave a Reply