df.groupby('Category').agg({'Item':'size','shop1':['sum','mean','std'],'shop2':['sum','mean','std'],'shop3':['sum','mean','std']})

Or if you want it across all shops then:

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']})
Answer from Scott Boston on Stack Overflow
Top answer
1 of 4
46
df.groupby('Category').agg({'Item':'size','shop1':['sum','mean','std'],'shop2':['sum','mean','std'],'shop3':['sum','mean','std']})

Or if you want it across all shops then:

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']})
2 of 4
34

Edited for Pandas 0.22+ considering the deprecation of the use of dictionaries in a group by aggregation.

We set up a very similar dictionary where we use the keys of the dictionary to specify our functions and the dictionary itself to rename the columns.

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
use agg ← link to 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
more for less
use describe ← link to 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
🌐
GeeksforGeeks
geeksforgeeks.org › pandas › pandas-group-by-multiple-columns
Pandas Group by Multiple Columns - GeeksforGeeks
July 23, 2025 - To group by multiple columns, you simply pass a list of column names to the groupby() function. ... Consider the following dataset. We will group by Category and Subcategory, and then calculate the sum of the Sales column.
🌐
Pandas
pandas.pydata.org › docs › user_guide › groupby.html
Group by: split-apply-combine — pandas 3.0.1 documentation
Here mean takes a GroupBy object and finds the mean of the Revenue and Quantity columns respectively for each Store-Product combination. The mean function can be any function that takes in a GroupBy object; the .pipe will pass the GroupBy object as a parameter into the function you specify.
🌐
Spark By {Examples}
sparkbyexamples.com › home › pandas › pandas groupby multiple columns explained
Pandas GroupBy Multiple Columns Explained - Spark By {Examples}
June 27, 2025 - ... The groupby() function allows you to group data based on multiple columns by passing a list of column names. You can apply aggregation functions (like sum, mean, count) to groups defined by multiple columns, making it easier to analyze data ...
🌐
Pandas
pandas.pydata.org › docs › reference › api › pandas.core.groupby.GroupBy.mean.html
pandas.core.groupby.GroupBy.mean — pandas 1.5.3 documentation
>>> df.groupby('A').mean() B C A 1 3.0 1.333333 2 4.0 1.500000 · Groupby two columns and return the mean of the remaining column.
🌐
Medium
medium.com › @heyamit10 › mastering-pandas-groupby-multiple-columns-92411999779f
Mastering pandas groupby Multiple Columns | by Hey Amit | Medium
April 12, 2025 - Let’s consider a dataset containing customer transactions across different stores. By using pandas groupby multiple columns, you can analyze purchase behaviors across customer segments, helping businesses tailor their marketing efforts effectively.
🌐
James LeDoux's Blog
jamesrledoux.com › code › group-by-aggregate-pandas
Group and Aggregate by One or More Columns in Pandas - James LeDoux’s Blog
June 1, 2019 - This dict takes the column that you’re aggregating as a key, and either a single aggregation function or a list of aggregation functions as its value. To apply aggregations to multiple columns, just add additional key:value pairs to the dictionary. # group by Team, get mean, min, and max ...
Find elsewhere
🌐
Statology
statology.org › home › how to calculate the mean by group in pandas (with examples)
How to Calculate the Mean by Group in Pandas (With Examples)
August 29, 2022 - You can use the following methods to calculate the mean value by group in pandas: Method 1: Calculate Mean of One Column Grouped by One Column · df.groupby(['group_col'])['value_col'].mean() Method 2: Calculate Mean of Multiple Columns Grouped by One Column ·
🌐
Pandas
pandas.pydata.org › pandas-docs › version › 0.25.0 › reference › api › pandas.core.groupby.GroupBy.mean.html
pandas.core.groupby.GroupBy.mean — pandas 0.25.0 documentation
>>> df.groupby('A').mean() B C A 1 3.0 1.333333 2 4.0 1.500000 · Groupby two columns and return the mean of the remaining column.
🌐
Saturn Cloud
saturncloud.io › blog › how-to-group-by-and-aggregate-on-multiple-columns-in-pandas
How to Group By and Aggregate on Multiple Columns in Pandas | Saturn Cloud Blog
January 23, 2024 - Once the data is grouped, we can ... each group. To group data by multiple columns in Pandas, we simply pass a list of column names to the groupby() method....
🌐
Pandas
pandas.pydata.org › docs › reference › api › pandas.core.groupby.DataFrameGroupBy.mean.html
pandas.core.groupby.DataFrameGroupBy.mean — pandas 2.3.3 documentation
>>> df.groupby(['A', 'B']).mean() C A B 1 2.0 2.0 4.0 1.0 2 3.0 1.0 5.0 2.0 · Groupby one column and return the mean of only particular column in the group.
🌐
Statology
statology.org › home › pandas: how to group and aggregate by multiple columns
Pandas: How to Group and Aggregate by Multiple Columns
August 7, 2022 - #group by team and position and find mean assists new = df.groupby(['team', 'position']).agg({'assists': ['mean']}).reset_index() #rename columns new.columns = ['team', 'pos', 'mean_assists'] #view DataFrame print(new) team pos mean_assists 0 A G 5.0 1 B F 6.0 2 B G 7.5 3 M C 7.5 4 M F 7.0 · Assume we use the same pandas DataFrame as the previous example:
🌐
GeeksforGeeks
geeksforgeeks.org › pandas › python-pandas-dataframe-groupby
Pandas dataframe.groupby() Method - GeeksforGeeks
Pandas groupby() function is a powerful tool used to split a DataFrame into groups based on one or more columns, allowing for efficient data analysis and aggregation. It follows a "split-apply-combine" strategy, where data is divided into groups, ...
Published   July 11, 2025
🌐
Saturn Cloud
saturncloud.io › blog › how-to-get-the-average-of-a-groupby-with-pandas
How to Get the Average of a Groupby with Pandas | Saturn Cloud Blog
October 23, 2023 - We also learned that to get the ... you can use the mean() method on the GroupBy object. This method calculates the mean of each numeric column for each group. Finally, we saw how to group a DataFrame by multiple columns by passing a list of column names to the groupby() method...
Top answer
1 of 4
59

If you call .reset_index() on the series that you have, it will get you a dataframe like you want (each level of the index will be converted into a column):

df.groupby(['name', 'id', 'dept'])['total_sale'].mean().reset_index()

EDIT: to respond to the OP's comment, adding this column back to your original dataframe is a little trickier. You don't have the same number of rows as in the original dataframe, so you can't assign it as a new column yet. However, if you set the index the same, pandas is smart and will fill in the values properly for you. Try this:

cols = ['date','name','id','dept','sale1','sale2','sale3','total_sale']
data = [
['1/1/17', 'John', 50, 'Sales', 50.0, 60.0, 70.0, 180.0],
['1/1/17', 'Mike', 21, 'Engg', 43.0, 55.0, 2.0, 100.0],
['1/1/17', 'Jane', 99, 'Tech', 90.0, 80.0, 70.0, 240.0],
['1/2/17', 'John', 50, 'Sales', 60.0, 70.0, 80.0, 210.0],
['1/2/17', 'Mike', 21, 'Engg', 53.0, 65.0, 12.0, 130.0],
['1/2/17', 'Jane', 99, 'Tech', 100.0, 90.0, 80.0, 270.0],
['1/3/17', 'John', 50, 'Sales', 40.0, 50.0, 60.0, 150.0],
['1/3/17', 'Mike', 21, 'Engg', 53.0, 55.0, 12.0, 120.0],
['1/3/17', 'Jane', 99, 'Tech', 80.0, 70.0, 60.0, 210.0]
]
df = pd.DataFrame(data, columns=cols)

mean_col = df.groupby(['name', 'id', 'dept'])['total_sale'].mean() # don't reset the index!
df = df.set_index(['name', 'id', 'dept']) # make the same index here
df['mean_col'] = mean_col
df = df.reset_index() # to take the hierarchical index off again
2 of 4
7

You are very close. You simply need to add a set of brackets around [['total_sale']] to tell python to select as a dataframe and not a series:

df.groupby(['name', 'id', 'dept'])[['total_sale']].mean()

If you want all columns:

df.groupby(['name', 'id', 'dept'], as_index=False).mean()[['name', 'id', 'dept', 'total_sale']]
🌐
datagy
datagy.io › home › pandas tutorials › grouping data in pandas › pandas groupby multiple columns explained with examples
Pandas GroupBy Multiple Columns Explained with Examples • datagy
September 17, 2023 - The Pandas groupby method is a ... complex calculations. One of the strongest benefits of the groupby method is the ability to group by multiple columns, and even apply multiple transformations....
🌐
GeeksforGeeks
geeksforgeeks.org › pandas › pandas-groupby-average
Pandas Groupby Average - GeeksforGeeks
July 23, 2025 - import pandas as pd data = { 'Name': ... 51000.0 Male 32.5 65000.0 · You can also group by multiple columns to calculate averages for more specific subgroups....