pola-rs/polars · error · ValueError
parameters `com`, `span`, `half_life`, and `alpha` are mutua
Error message
parameters `com`, `span`, `half_life`, and `alpha` are mutually exclusive
What it means
_prepare_alpha normalises the exponentially-weighted decay specification used by Expr.ewm_mean (and related EWM functions). The four ways to specify decay — com, span, half_life, alpha — are mutually exclusive because each alone determines the smoothing factor; supplying more than one is contradictory and raises ValueError before any computation starts.
Source
Thrown at py-polars/src/polars/expr/expr.py:12793
def _skip_batch_predicate(self, schema: SchemaDict) -> Expr | None:
result = self._pyexpr.skip_batch_predicate(schema)
if result is None:
return None
return wrap_expr(result)
def _prepare_alpha(
com: float | int | None = None,
span: float | int | None = None,
half_life: float | int | None = None,
alpha: float | int | None = None,
) -> float:
"""Normalise EWM decay specification in terms of smoothing factor 'alpha'."""
if sum((param is not None) for param in (com, span, half_life, alpha)) > 1:
msg = (
"parameters `com`, `span`, `half_life`, and `alpha` are mutually exclusive"
)
raise ValueError(msg)
if com is not None:
if com < 0.0:
msg = f"require `com` >= 0 (found {com!r})"
raise ValueError(msg)
alpha = 1.0 / (1.0 + com)
elif span is not None:
if span < 1.0:
msg = f"require `span` >= 1 (found {span!r})"
raise ValueError(msg)
alpha = 2.0 / (span + 1.0)
elif half_life is not None:
if half_life <= 0.0:
msg = f"require `half_life` > 0 (found {half_life!r})"
raise ValueError(msg)
alpha = 1.0 - math.exp(-math.log(2.0) / half_life)
View on GitHub (pinned to df599052da)
Solutions
- Keep exactly one decay parameter: com, span, half_life, or alpha.
- If migrating between specifications, convert the value once (e.g. span=10 implies alpha=2/11) and pass only alpha.
- Audit your config dict for EWM keys and strip all but one before calling.
Example fix
# before
pl.col('x').ewm_mean(com=0.5, span=10)
# after
pl.col('x').ewm_mean(span=10) Defensive patterns
Strategy: validation
Validate before calling
params = {'com': com, 'span': span, 'half_life': half_life, 'alpha': alpha}
provided = [k for k, v in params.items() if v is not None]
assert len(provided) == 1, f'exactly one decay param required, got {provided}' Prevention
- Model decay as one choice in config (an enum or oneof), not four optional numbers.
- Recall pandas ewm has the same exclusivity rule — porting code should already satisfy it.
When it happens
Trigger: pl.col('x').ewm_mean(com=0.5, span=10), ewm_mean(span=10, alpha=0.3), or any call where two of the four parameters are non-None.
Common situations: Copy-pasting an ewm_mean example that uses span and merging it with code that already sets com or alpha; config objects exposing all EWM knobs with several filled in; incremental edits that add a 'better' decay parameter without removing the old one.
Related errors
- require `com` >= 0 (found {com!r})
- require `span` >= 1 (found {span!r})
- require `half_life` > 0 (found {half_life!r})
- one of `com`, `span`, `half_life`, or `alpha` must be set
- require 0 < `alpha` <= 1 (found {alpha!r})
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/e70c5e22981db5f0.
Report an issue: GitHub.