pandas-dev/pandas · error · NotImplementedError

Named aggregation is not supported when {axis=}.

Error message

Named aggregation is not supported when {axis=}.

What it means

Raised by frame_apply when named aggregation (the **kwargs-as-named-columns syntax like df.agg(col=('sum')) or the dict/tuple form that resolves to columns) is used together with axis=1. Named aggregation defines output column names by applying functions to columns, which is only meaningful across rows (axis=0); applying it across columns is not implemented.

Source

Thrown at pandas/core/apply.py:246

    axis: Axis = 0,
    raw: bool = False,
    result_type: str | None = None,
    by_row: Literal[False, "compat"] = "compat",
    engine: str = "python",
    engine_kwargs: dict[str, bool] | None = None,
    args=None,
    kwargs=None,
) -> FrameApply:
    """construct and return a row or column based frame apply object"""
    _, func, columns, _ = reconstruct_func(func, **kwargs)

    axis = obj._get_axis_number(axis)
    klass: type[FrameApply]
    if axis == 0:
        klass = FrameRowApply
    elif axis == 1:
        if columns:
            raise NotImplementedError(
                f"Named aggregation is not supported when {axis=}."
            )
        klass = FrameColumnApply

    return klass(
        obj,
        func,
        raw=raw,
        result_type=result_type,
        by_row=by_row,
        engine=engine,
        engine_kwargs=engine_kwargs,
        args=args,
        kwargs=kwargs,
    )


class Apply(metaclass=abc.ABCMeta):

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Use axis=0 (the default) for named aggregation.
  2. For row-wise operations, use df.apply(func, axis=1) with a plain function (no named-aggregation kwargs) and rename the resulting Series afterward.
  3. Drop the named-aggregation kwargs when you must operate across columns.

Example fix

# before
df.agg(total=('A', 'sum'), axis=1)
# after
df.agg(total=('A', 'sum'))  # axis=0
df.apply(lambda row: row['A'].sum(), axis=1).rename('total')
Defensive patterns

Strategy: validation

Validate before calling

def named_agg(df, axis=0, **kwargs):
    has_named = any(isinstance(v, tuple) for v in kwargs.values())
    if has_named and axis == 1:
        raise NotImplementedError('named aggregation requires axis=0')
    return df.agg(axis=axis, **kwargs)

Type guard

def is_named_aggregation(func) -> bool:
    if isinstance(func, dict):
        return any(isinstance(v, tuple) and len(v) == 2 for v in func.values())
    return False

Prevention

When it happens

Trigger: df.agg(total=('A', 'sum'), axis=1); df.apply({'x': 'sum'}, axis=1) where the func resolves to named-aggregation columns; df.transform with named kwargs and axis=1.

Common situations: Switching an existing named-aggregation call from axis=0 to axis=1 expecting row-wise named output; generic apply wrappers that forward both named kwargs and an axis parameter.

Related errors


AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07). Data as JSON: /api/errors/2779ed1e6d3d5aaa. Report an issue: GitHub.