pandas groupby "function does not reduce" error fix
Fixes the pandas groupby 'function does not reduce' error. Use when df.groupby(...).agg(func) or apply with a custom function raises 'function does not reduce', or when an aggregation silently returns wrong-shaped results. Do not use for ordinary groupby syntax help, transform usage, or general slow-groupby problems.
TL;DR
This error means the function you passed to .agg or .apply returned a Series or DataFrame instead of a single scalar per group. Fix it by making your function return one scalar value (a float, int, string) per group. It happens because pandas expected a reduction (many rows to one value) and got something else back.
ValueError: Function does not reduceUse this when
df.groupby('col').agg(my_func)raisesValueError: Function does not reduce- A lambda in
.aggor.applyreturns a Series instead of a scalar - Groupby aggregation returns an unexpected shape or errors after a pandas upgrade
Not for
- Basic groupby how-to, use the pandas groupby docs
.transformusage (returns one value per row, not per group)- Groupby performance problems, different topic
Steps
- Find the offending function. Reproduce on one group:
df.groupby('col').get_group(df['col'].iloc[0]).pipe(my_func)Expected output: you will see it returns a Series/DataFrame, not a scalar.
- Rewrite the function to return a single scalar:
def my_func(s):
return float(s.max() - s.min())Expected output: calling my_func on one group's column returns one number.
- Rerun the aggregation:
df.groupby('col').agg(my_func)Expected output: one row per group, one column per aggregation.
- If you actually wanted a Series back per group, you meant
.apply, not.agg:
df.groupby('col').apply(my_func)Expected output: a result indexed by group, with the Series your function returns.
- Check the pandas version if old code broke:
import pandas as pd; pd.__version__Expected output: the version. In pandas 2.x, .agg is stricter about what counts as a reduction than in 1.x.
Variant phrasings
groupby agg ValueError function does not reduce
The canonical case. Your function returned non-scalar output to .agg.
function does not reduce after upgrading pandas
Pandas 2.x tightened the rules: functions that happened to work in 1.x because of lenient coercion now raise. Wrap or rewrite to return a scalar explicitly.
custom aggregation function groupby error
If the function works outside groupby but fails inside it, the mismatch is the group Series it receives. Test it standalone on a slice (step 1) to see.
Why it happens
.agg is a reduction: it feeds each group to your function and expects exactly one scalar back per group. If your function returns a Series, pandas cannot collapse that into the single-row-per-group result, so it raises. .apply is the flexible sibling that accepts any return shape.
Edge cases
- String-returning functions are fine as long as it is one string per group.
- Returning
np.nanor None counts as scalar, no error. - Mixed
aggdicts like{'a': 'sum', 'b': my_func}: only the custom function needs to reduce. - If you need multiple scalars per group, return a dict or use named aggregation:
df.groupby('col').agg(total=('x','sum'), spread=('x', my_func)).
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_AOQ-OdCIQPXj3TYZmcHbJg
Maintainer review
No maintainer verification is recorded for this version.
This records the version a maintainer checked. It does not assert that the version is the latest upstream release.