web-dev-qa-db-fra.com

Les pandas pythons se regroupent en plusieurs colonnes, puis pivotent

En Python, j'ai un DataFrame similaire à celui-ci:

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 différents magasins ..__ Maintenant, je dois retourner un DataFrame, après un nettoyage des données, comme celui-ci:

Category (index)| size| sum| mean | std
----------------------------------------

où size est le nombre d'articles dans chaque catégorie et sum, mean et std sont liés aux mêmes fonctions que celles appliquées aux 3 magasins. Comment puis-je effectuer ces opérations avec le modèle fractionner-appliquer-combiner (groupby, agréger, appliquer, ...)?

Est-ce que quelqu'un peut m'aider? Je deviens fou avec celui-ci ... merci!

15

Édité pour Pandas 0.22+ en considérant la dépréciation de l'utilisation des dictionnaires dans un groupe par agrégation.

Nous avons créé un dictionnaire très similaire dans lequel nous utilisons les clés 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
utilisez agg ← lien vers les documents

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
utilisez describe ← lien vers les documents 

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
16
piRSquared
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']})
7
Scott Boston

Si je comprends bien, vous souhaitez calculer des métriques globales pour tous les magasins, pas pour chacun individuellement. Pour ce faire, vous pouvez d’abord stack votre structure de données, puis regrouper 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']})

Ce qui résulte en 

           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
0
foglerit