pola-rs/polars · error
cannot call `map_groups` when filtering groups with `having`
Error message
cannot call `map_groups` when filtering groups with `having`
What it means
`df.group_by(...).map_groups(...)` applies a Python function per group. Polars rejects this when the GroupBy also carries `having` predicates (filtering groups), because group-level filtering combined with arbitrary map_groups output has no well-defined result.
Solutions
- Apply the group filter before/without having: compute groups with map_groups first, then `filter` the resulting DataFrame.
- Use `filter` over a window function instead of `having`: `df.filter(cond.over(group_cols))` then group_by/map_groups.
- Split into two steps: aggregate with having, then map_groups on the filtered frame.
- Restructure the function so filtering happens inside the per-group function.
Example fix
// before
df.group_by('g').having(pl.len() > 2).map_groups(fn)
// after
df.group_by('g').map_groups(fn).filter(pl.len() > 2) # or filter groups pre-hoc Defensive patterns
Strategy: try-catch
Try / catch
try:
out = gb.map_groups(fn)
except TypeError as e:
if 'having' in str(e):
out = df.filter(cond.over(group_cols)).group_by(group_cols).map_groups(fn) Prevention
- Do not combine having() with map_groups in the same GroupBy
- Filter groups with window functions (cond.over(...)) before group_by
- Keep having for pure aggregations only
When it happens
Trigger: Calling `.group_by(cols).having(pl.col('x') > 1).map_groups(fn)` — i.e. any map_groups after a `having` filter.
Common situations: Building a query fluently where having-filtering was added for an aggregate step and then reused for map_groups; porting SQL HAVING logic onto a map_groups pipeline.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- cannot call `map_groups` when grouping by an expression
- cannot call `map_groups` when grouping by named expressions
- arr.to_struct() got a str instead of a list. hint: pass
- cannot set Series of dtype
- cannot use " " for indexing
AI-assisted analysis of pola-rs/polars@fe841f959e (2026-09-18).
Data as JSON: /api/errors/74834632fb67de94.
Report an issue: GitHub.
Appendix: source
Thrown at py-polars/src/polars/dataframe/group_by.py:441
│ id ┆ color ┆ shape │
│ --- ┆ --- ┆ --- │
│ i64 ┆ str ┆ str │
╞═════╪═══════╪══════════╡
│ 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
----------View on GitHub (pinned to fe841f959e)