pandas-dev/pandas · error · ValueError
cannot combine transform and aggregation operations
Error message
cannot combine transform and aggregation operations
What it means
Raised inside `wrap_results_list_like` when concat of per-function results fails with TypeError and the resulting fallback Series is a 'nested object' — meaning some functions returned scalar aggregations while others returned NDFrame-shaped transforms. Mixing these two operation kinds in a single list-like call is structurally ambiguous.
Source
Thrown at pandas/core/apply.py:540
keys = selected_obj.columns.take(indices) # type: ignore[assignment]
return keys, results
def wrap_results_list_like(
self, keys: Iterable[Hashable], results: list[Series | DataFrame]
):
obj = self.obj
try:
return concat(results, keys=keys, axis=1, sort=False)
except TypeError as err:
# we are concatting non-NDFrame objects,
# e.g. a list of scalars
from pandas import Series
result = Series(results, index=keys, name=obj.name)
if is_nested_object(result):
raise ValueError(
"cannot combine transform and aggregation operations"
) from err
return result
def agg_dict_like(self) -> DataFrame | Series:
"""
Compute aggregation in the case of a dict-like argument.
Returns
-------
Result of aggregation.
"""
return self.agg_or_apply_dict_like(op_name="agg")
def compute_dict_like(
self,
op_name: Literal["agg", "apply"],
selected_obj: Series | DataFrame,View on GitHub (pinned to 71959b8cb9)
Solutions
- Separate the call into an aggregation pass and a transform pass: `df.agg(['sum', 'mean'])` then `df.transform([elemwise_fn])`.
- Replace the offending function with one that consistently returns either scalars (for agg) or same-shaped output (for transform).
- Use a dict form with explicit column→function mapping to make intent unambiguous.
Example fix
# before df.agg(['sum', lambda s: s + 1]) # after agg_part = df.agg(['sum']) trans_part = df.transform(lambda s: s + 1)
Defensive patterns
Strategy: validation
Validate before calling
import pandas as pd
def classify(func, s):
out = func(s)
return 'transform' if isinstance(out, pd.Series) and out.index.equals(s.index) else 'agg'
def split_funcs(funcs, s):
agg, trans = [], []
for f in funcs:
(trans if classify(f, s) == 'transform' else agg).append(f)
return agg, trans Type guard
def is_homogeneous_return(funcs, s) -> bool:
kinds = {classify(f, s) for f in funcs}
return len(kinds) == 1 Try / catch
try:
df.agg(funcs)
except ValueError as e:
if 'cannot combine transform and aggregation' in str(e):
# split into agg and transform passes
...
raise Prevention
- Do not mix scalar-returning and same-shape-returning functions in one list.
- Split heterogeneous function lists into separate agg/transform calls.
When it happens
Trigger: `df.agg(['sum', lambda s: s])` — `sum` aggregates to a scalar, the lambda returns same-shape Series (transform). The list mixes reduce and broadcast semantics, so pandas cannot decide the output shape.
Common situations: Combining named aggregations with custom element-wise functions in one list; copy-pasting a mixed function list from a tutorial; refactoring where a transform function slipped into an agg list.
Related errors
- cannot perform both aggregation and transformation operation
- Transform function failed
- Function did not transform
- No transform functions were provided
- invalid value for result_type, must be one of {None, 'reduce
AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07).
Data as JSON: /api/errors/95ecfc95abe9b387.
Report an issue: GitHub.