Python pandas groupby agregat pada beberapa kolom, lalu pivot

Dalam Python, saya memiliki DataFrame pandas yang mirip dengan berikut ini:

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

Di mana shop1, shop2 dan shop3 adalah biaya setiap item di toko yang berbeda. Sekarang, saya perlu mengembalikan DataFrame, setelah beberapa pembersihan data, seperti ini:

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

di mana ukuran adalah jumlah item di setiap Kategori dan jumlah, rata-rata dan std terkait dengan fungsi yang sama yang diterapkan pada 3 toko. Bagaimana saya bisa melakukan operasi ini dengan pola split-apply-combine (groupby, aggregate, apply,...) ?

Dapatkah seseorang membantu saya? Saya akan gila dengan yang satu ini...terima kasih!

Larutan

Diedit untuk Pandas 0.22+ dengan mempertimbangkan tidak digunakannya lagi penggunaan kamus dalam grup dengan agregasi.

Kami menyiapkan kamus yang sangat mirip di mana kami menggunakan kunci kamus untuk menentukan fungsi kami dan kamus itu sendiri untuk mengganti nama kolom.

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

opsi 1 gunakan agg ← tautan ke dokumen

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

pilihan 2 lebih banyak untuk lebih sedikit pakai describe ← tautan ke dokumen

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
Komentar (2)
df.groupby('Category').agg({'Item':'size','shop1':['sum','mean','std'],'shop2':['sum','mean','std'],'shop3':['sum','mean','std']})

Atau jika Anda menginginkannya di semua toko:

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']})
Komentar (0)

Jika saya mengerti dengan benar, Anda ingin menghitung metrik agregat untuk semua toko, bukan untuk masing-masing toko secara individual. Untuk melakukan itu, pertama-tama Anda dapat stack dataframe Anda dan kemudian mengelompokkan berdasarkan Kategori:

stacked = df.set_index(['Item', 'Category']).stack().reset_index()
stacked.columns = ['Item', 'Category', 'Shop', 'Price']
stacked.groupby('Category').agg({'Price':['count','sum','mean','std']})

Yang menghasilkan

           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
Komentar (0)