100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Python

Aggregation Functions

Explore the built-in and custom aggregation functions available after groupby, including agg() for applying multiple statistics at once.

Grouping & AggregationIntermediate9 min readJul 8, 2026
Analogies

Aggregation Functions

Once a GroupBy object exists, an aggregation function collapses each group down to a single summary value (or a small set of values) per group. pandas ships many built-in aggregators — sum, mean, median, min, max, std, var, count, nunique, first, last — each optimized in Cythonized code for speed. Beyond calling these individually, the .agg() (alias .aggregate()) method is the Swiss-army knife of group summarization: it accepts a single function name, a list of function names to compute simultaneously, or a dictionary mapping specific columns to specific functions, giving you precise control over what gets computed and how results are labeled.

🏏

Cricket analogy: Once you group deliveries by bowler, an aggregator like sum or mean collapses each bowler's overs into one figure such as economy rate, and .agg() lets you request sum, mean and wicket count for Bumrah's spell all in one call.

Multiple Aggregations with agg()

Passing a list to .agg(), such as .agg(['sum', 'mean', 'count']), computes all three statistics for every selected column and returns a DataFrame with a column for each function. When different columns need different treatment — say, summing revenue but averaging discount_pct — a dictionary form like .agg({'revenue': 'sum', 'discount_pct': 'mean'}) applies each function only to its associated column. Named aggregation, using keyword arguments of the form new_col=('source_col', 'func'), goes a step further by letting you produce flatly-named output columns in one pass, avoiding the MultiIndex columns that list-based agg() produces.

🏏

Cricket analogy: Passing .agg(['sum','mean','count']) to a bowling group computes wickets, economy and matches together, while a dict like .agg({'runs':'sum','strike_rate':'mean'}) sums runs but averages strike rate per batter.

python
import pandas as pd

sales = pd.DataFrame({
    'region': ['East', 'East', 'West', 'West', 'West'],
    'revenue': [1200, 800, 950, 1600, 700],
    'discount_pct': [0.1, 0.05, 0.15, 0.0, 0.2]
})

# multiple stats on one column
stats = sales.groupby('region')['revenue'].agg(['sum', 'mean', 'count'])
print(stats)

# different function per column via dict
mixed = sales.groupby('region').agg({'revenue': 'sum', 'discount_pct': 'mean'})
print(mixed)

# named aggregation avoids MultiIndex columns
clean = sales.groupby('region').agg(
    total_revenue=('revenue', 'sum'),
    avg_discount=('discount_pct', 'mean'),
    n_orders=('revenue', 'count')
)
print(clean)
#         total_revenue  avg_discount  n_orders
# region
# East              2000        0.075         2
# West              3250        0.117         3

Custom Aggregation Functions

Any function that reduces a Series (or array) to a single scalar can be passed to .agg(), including lambdas and user-defined functions, e.g. .agg(lambda s: s.max() - s.min()) to compute a per-group range. Custom functions are convenient but slower than built-in string names because pandas cannot use its optimized Cython implementations for arbitrary Python callables — prefer built-in names (or NumPy ufuncs like np.ptp) when performance on large groups matters.

🏏

Cricket analogy: A custom lambda like .agg(lambda s: s.max() - s.min()) on a batter's innings computes the range between their highest and lowest score per series, but it runs slower than pandas' built-in max and min since Python executes it per group.

nunique() is a frequently underused aggregator: df.groupby('customer')['product'].nunique() answers 'how many distinct products did each customer buy?' — distinct from count(), which simply counts non-null rows including repeats.

Mixing string function names and callables in a single .agg() list, e.g. .agg(['sum', lambda x: x.max()]), produces an awkwardly named column like '<lambda>' — always rename or use named aggregation for clarity in production code.

  • Built-in aggregators (sum, mean, count, nunique, etc.) are optimized and should be preferred over custom lambdas when possible.
  • .agg() accepts a single function, a list of functions, or a dict mapping columns to functions.
  • Named aggregation (new_col=('source', 'func')) produces flat, clearly labeled output columns.
  • nunique() counts distinct values per group, while count() counts non-null occurrences (including duplicates).
  • Custom callables passed to agg() run in pure Python and are slower than built-in string-named aggregators.
  • Aggregation always reduces each group to a fixed-size summary, unlike transform which preserves the original shape.

Practice what you learned

Was this page helpful?

Topics covered

#Python#PandasNumPyStudyNotes#DataScience#AggregationFunctions#Aggregation#Functions#Multiple#Aggregations#StudyNotes#SkillVeris