pola-rs/polars · error
cannot call `map_groups` when grouping by named expressions
Error message
cannot call `map_groups` when grouping by named expressions
What it means
GroupBy.map_groups hands each group's sub-DataFrame to a Python function via the Rust group_by_map_groups path, which identifies groups by plain column names only. Named expressions (keyword arguments like df.group_by(grp=pl.col('a') + 1)) create derived/aliased keys that this path cannot resolve back to columns, so polars raises TypeError when the GroupBy object carries any named_by entries.
Source
Thrown at py-polars/src/polars/dataframe/group_by.py:450
╞═════╪═══════╪══════════╡
│ 1 ┆ green ┆ triangle │
│ 2 ┆ green ┆ square │
│ 4 ┆ red ┆ square │
│ 3 ┆ red ┆ triangle │
└─────┴───────┴──────────┘
It is better to implement this with an expression:
>>> df.filter(
... pl.int_range(pl.len()).shuffle().over("color") < 2
... ) # doctest: +IGNORE_RESULT
"""
if self.predicates:
msg = "cannot call `map_groups` when filtering groups with `having`"
raise TypeError(msg)
if self.named_by:
msg = "cannot call `map_groups` when grouping by named expressions"
raise TypeError(msg)
by = list(_parse_inputs_as_iterable(self.by))
if not all(isinstance(c, str) for c in by):
msg = "cannot call `map_groups` when grouping by an expression"
raise TypeError(msg)
return self.df.__class__._from_pydf(
self.df._df.group_by_map_groups(by, function, self.maintain_order)
)
def head(self, n: int = 5) -> DataFrame:
"""
Get the first `n` rows of each group.
Parameters
----------
n
Number of rows to return.
View on GitHub (pinned to df599052da)
Solutions
- Group by plain column names only: df.group_by('a').map_groups(fn)
- Precompute derived keys as a column first: df.with_columns((pl.col('a') % 10).alias('grp')).group_by('grp').map_groups(fn)
- Rename or alias the key after map_groups if a different output name is needed
Example fix
# before
out = df.group_by(grp=pl.col('a') % 10).map_groups(process_group)
# after
out = (
df.with_columns((pl.col('a') % 10).alias('grp'))
.group_by('grp')
.map_groups(process_group)
) Defensive patterns
Strategy: validation
Validate before calling
def safe_map_groups(gb, fn):
if getattr(gb, 'named_by', None):
raise TypeError('map_groups requires plain column-name keys; precompute derived keys as columns')
return gb.map_groups(fn) Prevention
- Reserve kwargs (named expressions) for .agg pipelines; use positional column names for map_groups
- Materialize derived keys with with_columns(...).alias(...) before grouping
- Alias/rename grouping keys after map_groups rather than at group_by time
When it happens
Trigger: df.group_by(grp=pl.col('a') % 10).map_groups(fn); any group_by call using keyword=Expr arguments and then chaining .map_groups(...); refactors that renamed grouping keys via kwargs for readability.
Common situations: Using named-expression syntax (fine for .agg) on pipelines that end in map_groups; deriving grouping keys on the fly (alias in the group_by) instead of precomputing a column; mixed style within a codebase.
Related errors
- cannot call `map_groups` when filtering groups with `having`
- Expected Polars expression or object convertible to one, got
- cannot select columns using key of type {qualified_type_name
- cannot select rows using key of type {qualified_type_name(ke
- cannot treat Series of type {s.dtype} as indices
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/03925b03ad776ec1.
Report an issue: GitHub.