Python pandas groupby globale sur plusieurs colonnes, puis faites pivoter
en Python, j'ai une DataFrame de pandas similaire à la suivante:
Item | shop1 | shop2 | shop3 | Category
------------------------------------
Shoes| 45 | 50 | 53 | Clothes
TV | 200 | 300 | 250 | Technology
Book | 20 | 17 | 21 | Books
phone| 300 | 350 | 400 | Technology
<!-Où shop1, shop2 et shop3 sont les coûts de chaque article dans les différents magasins.
Maintenant, je dois retourner une DataFrame, après quelques nettoyages de données, comme celle-ci:
Category (index)| size| sum| mean | std
----------------------------------------
où la taille est le nombre d'articles dans chaque catégorie et la somme, la moyenne et la MST sont liées aux mêmes fonctions appliquées aux 3 ateliers. Comment puis-je effectuer ces opérations avec le split-appliquer-combiner motif (groupby, agréger, appliquer,...) ?
quelqu'un Peut-il m'aider? Je deviens folle avec celui-là...je vous remercie!
3 réponses
édité pour Pandas 0.22+ considérant la dévalorisation de l'utilisation des dictionnaires dans un groupe par agrégation.
nous avons mis en place un dictionnaire très similaire où nous utilisons les touches du dictionnaire pour spécifier nos fonctions et le dictionnaire lui-même pour renommer les colonnes.
rnm_cols = dict(size='Size', sum='Sum', mean='Mean', std='Std')
df.set_index(['Category', 'Item']).stack().groupby('Category') \
.agg(rnm_cols.keys()).rename(columns=rnm_cols)
Size Sum Mean Std
Category
Books 3 58 19.333333 2.081666
Clothes 3 148 49.333333 4.041452
Technology 6 1800 300.000000 70.710678
option 1
utiliser agg
← lien docs
agg_funcs = dict(Size='size', Sum='sum', Mean='mean', Std='std')
df.set_index(['Category', 'Item']).stack().groupby(level=0).agg(agg_funcs)
Std Sum Mean Size
Category
Books 2.081666 58 19.333333 3
Clothes 4.041452 148 49.333333 3
Technology 70.710678 1800 300.000000 6
option 2
plus pour moins
utiliser describe
← lien vers docs
df.set_index(['Category', 'Item']).stack().groupby(level=0).describe().unstack()
count mean std min 25% 50% 75% max
Category
Books 3.0 19.333333 2.081666 17.0 18.5 20.0 20.5 21.0
Clothes 3.0 49.333333 4.041452 45.0 47.5 50.0 51.5 53.0
Technology 6.0 300.000000 70.710678 200.0 262.5 300.0 337.5 400.0
df.groupby('Category').agg({'Item':'size','shop1':['sum','mean','std'],'shop2':['sum','mean','std'],'shop3':['sum','mean','std']})
Ou si vous le souhaitez dans tous les magasins alors:
df1 = df.set_index(['Item','Category']).stack().reset_index().rename(columns={'level_2':'Shops',0:'costs'})
df1.groupby('Category').agg({'Item':'size','costs':['sum','mean','std']})
si je comprends bien, vous voulez calculer des mesures agrégées pour tous les magasins, pas pour chacun individuellement. Pour ce faire, vous pouvez d'abord stack
votre dataframe et puis groupez par Category
:
stacked = df.set_index(['Item', 'Category']).stack().reset_index()
stacked.columns = ['Item', 'Category', 'Shop', 'Price']
stacked.groupby('Category').agg({'Price':['count','sum','mean','std']})
résultats
Price
count sum mean std
Category
Books 3 58 19.333333 2.081666
Clothes 3 148 49.333333 4.041452
Technology 6 1800 300.000000 70.710678