J'ai ce df:
d = pd.DataFrame({'Name':['Andres','Lars','Paul','Mike'],
'target':['A','A','B','C'],
'number':[10,12.3,11,6]})
Et je veux classer chaque nombre dans un quartile. je fais ceci:
(d.groupby(['Name','target','number'])['number']
.quantile([0.25,0.5,0.75,1]).unstack()
.reset_index()
.rename(columns={0.25:"1Q",0.5:"2Q",0.75:"3Q",1:"4Q"})
)
Mais comme vous pouvez le voir, les 4 quartiles sont tous égaux car le code ci-dessus calcule par ligne, donc s'il y a un 1 nombre par ligne, tous les quartiles sont égaux.
Si une course à la place :
d['number'].quantile([0.25,0.5,0.75,1])
Ensuite, j'ai les 4 quartiles que je recherche:
0.25 9.000
0.50 10.500
0.75 11.325
1.00 12.300
Ce dont j'ai besoin en sortie (montrant seulement les 2 premières lignes)
Name target number 1Q 2Q 3Q 4Q Rank
0 Andres A 10.0 9.0 10.5 11.325 12.30 1
1 Lars A 12.3 9.0 10.5 11.325 12.30 4
vous pouvez voir que tous les quartiles ont les valeurs en tenant compte des valeurs élevées dans la number
colonne. En plus de cela, nous avons maintenant des noms de colonne Rank
qui classent le nombre en fonction de son quartile. ex. Dans la première rangée, 10 se situent dans le 1er quartile.
Solution du problème
Voici une façon de s'appuyer sur les quantiles que vous avez créés en en faisant un DataFrame et en l'intégrant join
à d
. Aussi assign
la colonne "Classement" utilisant la rank
méthode :
out = (d.join(d['number'].quantile([0.25,0.5,0.75,1])
.set_axis([f'{i}Q' for i in range(1,5)], axis=0)
.to_frame().T
.pipe(lambda x: x.loc[x.index.repeat(len(d))])
.reset_index(drop=True))
.assign(Rank=d['number'].rank(method='dense')))
Production:
Name target number 1Q 2Q 3Q 4Q Rank
0 Andres A 10.0 9.0 10.5 11.325 12.3 2.0
1 Lars A 12.3 9.0 10.5 11.325 12.3 4.0
2 Paul B 11.0 9.0 10.5 11.325 12.3 3.0
3 Mike C 6.0 9.0 10.5 11.325 12.3 1.0
Aucun commentaire:
Enregistrer un commentaire