Python pandas группировать по нескольким столбцам, затем сворачивать
В Python у меня есть pandas DataFrame, подобный следующему:
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
Где shop1, shop2 и shop3 - это затраты на каждый предмет в разных магазинах.
Теперь мне нужно вернуть DataFrame после очистки данных, например:
Category (index)| size| sum| mean | std
----------------------------------------
где size - количество элементов в каждой категории, а сумма, средняя и std связаны с теми же функциями, которые применяются к 3 магазинам. Как я могу выполнять эти операции с помощью шаблона split-apply-comb (groupby, aggregate, apply,...)?
Может кто-нибудь помочь мне? Я схожу с ума от этого... спасибо!
Ответы
Ответ 1
вариант 1
используйте agg
← ссылка на 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
вариант 2
больше за меньшее
используйте describe
← ссылка на 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
Ответ 2
df.groupby('Category').agg({'Item':'size','shop1':['sum','mean','std'],'shop2':['sum','mean','std'],'shop3':['sum','mean','std']})
Или, если вы хотите это во всех магазинах, тогда:
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']})
Ответ 3
Если я правильно понимаю, вы хотите рассчитать совокупные показатели для всех магазинов, а не для каждого отдельно. Для этого вы можете сначала stack
ваш файл данных, а затем группу 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']})
В результате получается
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