Comment pouvons-nous écrire une fonction qui agrégera, classera, classera chaque colonne du df, renommera l'agrégat en ajoutant un préfixe, des colonnes classées et classées, puis joindra les nouvelles colonnes rank & bin au df ?

Import pandas as pd
data = {"index_id": range(101, 131),
        'company': ['Opera', 'Opera', 'Opera', 'Opera', 'Opera', 'Opera',
                    'Firefox', 'Firefox', 'Firefox', 'Firefox', 'Firefox', 'Firefox',
                    'Safari', 'Safari', 'Safari', 'Safari', 'Safari', 'Safari',
                    'Brave', 'Brave', 'Brave', 'Brave', 'Brave', 'Brave',
                    'Chrome', 'Chrome', 'Chrome', 'Chrome', 'Chrome', 'Chrome'],
        "rating": [4, 5, 3, 3, 3, 3,
                   4, 5, 5, 1, 5, 5,
                   1, 4, 1, 2, 1, 2,
                   1, 5, 1, 5, 1, 5,
                   5, 5, 5, 4, 5, 4]
        }
df = pd.DataFrame(data)
df = df.groupby(['company']).agg({'rating':['std', 'mean']})
df.columns = ['rating_std', 'rating_mean']
df_rank = df.rank(ascending = 0, method = 'dense').add_prefix('rank_')
output = df_rank.copy(deep=True)
bin_labels = ['Bronze', 'Silver', 'Gold', 'Platinum', 'Diamond']
output['bin_rank_rating_std'] = pd.qcut(output['rank_rating_std'],
                              q=[0, .2, .4, .6, .8, 1],
                              labels=bin_labels)
output['bin_rank_rating_mean'] = pd.qcut(output['rank_rating_mean'],
                              q=[0, .2, .4, .6, .8, 1],
                              labels=bin_labels)

Dans df_rank, j'ai pu classer l'écart type et la moyenne, puis ajouter le préfixe du classement, mais je ne pouvais pas comprendre comment classer et renommer chaque colonne classée sans écrire chaque colonne. Je veux écrire une fonction ou utiliser une boucle for car avec mon jeu de données d'origine. J'ai 30 colonnes que je vais classer et classer, donc je ne peux pas nommer chacune d'elles dans une fonction. La sortie de la trame de données sera à quoi elle devrait ressembler.

1
BrianBeing 30 janv. 2020 à 09:20

1 réponse

Meilleure réponse

Utilisez DataFrame.applyavec fonction lambda, puis DataFrame.add_prefix et DataFrame.join à l'original DataFrame :

#simplify for not necessary set new columns names by list
df = df.groupby(['company'])['rating'].agg(['std', 'mean']).add_prefix('rating_')

df_rank = df.rank(ascending = 0, method = 'dense').add_prefix('rank_')

bin_labels = ['Bronze', 'Silver', 'Gold', 'Platinum', 'Diamond']
output = df_rank.apply(lambda x:pd.qcut(x, q=[0, .2, .4, .6, .8, 1], labels=bin_labels))
output = df_rank.join(output.add_prefix('bin_'))
print (output)
         rank_rating_std  rank_rating_mean bin_rank_rating_std  \
company                                                          
Brave                1.0               4.0              Bronze   
Chrome               5.0               1.0             Diamond   
Firefox              2.0               2.0              Silver   
Opera                4.0               3.0            Platinum   
Safari               3.0               5.0                Gold   

        bin_rank_rating_mean  
company                       
Brave               Platinum  
Chrome                Bronze  
Firefox               Silver  
Opera                   Gold  
Safari               Diamond  
1
jezrael 30 janv. 2020 à 06:26