pandas-dev/pandas · error · TypeError
Cannot perform {how} with non-ordered Categorical
Error message
Cannot perform {how} with non-ordered Categorical What it means
Raised by Categorical._groupby_op when the aggregation is order-based (min, max, rank, idxmin, idxmax) but the categorical dtype is unordered. Min/max/rank require a total ordering; an unordered categorical defines only a label set, so these operations are undefined. The comment in source notes this is raised as TypeError deliberately to avoid a slower per-group path that would also fail.
Source
Thrown at pandas/core/arrays/categorical.py:2876
has_dropped_na: bool,
min_count: int,
ngroups: int,
ids: npt.NDArray[np.intp],
**kwargs,
):
from pandas.core.groupby.ops import WrappedCythonOp
kind = WrappedCythonOp.get_kind_from_how(how)
op = WrappedCythonOp(how=how, kind=kind, has_dropped_na=has_dropped_na)
dtype = self.dtype
if how in ["sum", "prod", "cumsum", "cumprod", "skew", "kurt"]:
raise TypeError(f"{dtype} type does not support {how} operations")
if how in ["min", "max", "rank", "idxmin", "idxmax"] and not dtype.ordered:
# raise TypeError instead of NotImplementedError to ensure we
# don't go down a group-by-group path, since in the empty-groups
# case that would fail to raise
raise TypeError(f"Cannot perform {how} with non-ordered Categorical")
if how not in [
"rank",
"any",
"all",
"first",
"last",
"min",
"max",
"idxmin",
"idxmax",
]:
if kind == "transform":
raise TypeError(f"{dtype} type does not support {how} operations")
raise TypeError(f"{dtype} dtype does not support aggregation '{how}'")
result_mask = None
mask = self.isna()
if how == "rank":View on GitHub (pinned to 71959b8cb9)
Solutions
- Make the column ordered: df['cat'] = df['cat'].cat.as_ordered() (or pd.Categorical(..., ordered=True) with explicit categories).
- Use .first()/.last() instead of min/max if ordering is not meaningful.
- Cast to the underlying value dtype and aggregate there.
Example fix
// before
df.groupby('g')['cat'].min() # TypeError: Cannot perform min with non-ordered Categorical
// after
df['cat'] = df['cat'].cat.as_ordered()
df.groupby('g')['cat'].min() Defensive patterns
Strategy: validation
Validate before calling
ORDER_HOW = {'min','max','rank','idxmin','idxmax'}
def ensure_ordered_for_how(s, how):
import pandas as pd
if isinstance(s.dtype, pd.CategoricalDtype) and how in ORDER_HOW and not s.cat.ordered:
return s.cat.as_ordered()
return s Type guard
import pandas as pd
from typing import Any
def can_perform_order_op(obj: Any, how: str) -> bool:
dt = getattr(obj, 'dtype', None)
if isinstance(dt, pd.CategoricalDtype):
return dt.ordered or how not in {'min','max','rank','idxmin','idxmax'}
return True Try / catch
try:
df.groupby('g')['cat'].min()
except TypeError as e:
if 'non-ordered Categorical' in str(e):
df['cat'] = df['cat'].cat.as_ordered()
else:
raise Prevention
- Mark ordinal category columns ordered=True at creation.
- Guard groupby min/max/rank with an ordered check on category columns.
When it happens
Trigger: df.groupby('g')['cat'].min(), .max(), .rank(), .idxmin(), or .idxmax() on an unordered category column.
Common situations: A 'low/med/high' or 'cold/warm/hot' style column created without ordered=True; groupby pipelines that compute extrema or ranks on every categorical column.
Related errors
- 'values' is not ordered, please explicitly specify the categ
- Categorical is not ordered for operation {op} you can use .a
- {dtype} type does not support {how} operations
- numpy operations are not valid with groupby. Use .groupby(..
- dtype '{self.dtype}' does not support operation '{how}'
AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07).
Data as JSON: /api/errors/2b2861f2abc1a5ec.
Report an issue: GitHub.