apache/beam · error · ValueError
ZScore.learn_one expected univariate input, but got
Error message
ZScore.learn_one expected univariate input, but got %s
What it means
ZScore.learn_one updates the mean/standard-deviation trackers and expects x to be a beam.Row with exactly one numerical field. Any other field count raises ValueError. The z-score statistic is inherently univariate, so the detector enforces the input shape at learning time.
Solutions
- Project to one numeric field: beam.Map(lambda r: beam.Row(value=r.x)).
- Run one detector per feature for multivariate datasets.
- Validate row arity upstream with a Map that raises a clearer domain-specific error.
Example fix
// before rows | anomaly.ZScore(threshold=3).learn_one() # Row(a=.., b=..) // after rows | beam.Map(lambda r: beam.Row(value=r.a)) | anomaly.ZScore(threshold=3).learn_one()
Defensive patterns
Strategy: validation
Validate before calling
if len(row.__dict__) != 1:
raise ValueError(f"ZScore.learn_one requires exactly one field, got: {list(row.__dict__)}") Type guard
def is_univariate(row): return len(getattr(row, '__dict__', {})) == 1 Try / catch
try:
detector.learn_one(row)
except ValueError as e:
logger.warning("skipping row %r: %s", row, e) Prevention
- Project to beam.Row(value=...) before learn_one
- Keep IDs/timestamps out of detector input Rows
- Share one projection DoFn between learn and score paths
When it happens
Trigger: Calling ZScore.learn_one with a multi-field or empty beam.Row, e.g. beam.Row(mean=1, std=0.5) or a Row derived from a multi-column record.
Common situations: Multi-metric pipelines reused as-is; rows carrying identifiers or timestamps as extra attributes; schema drift in the source PCollection.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- "IQR.learn_one expected univariate input, but got
- "IQR.score_one expected univariate input, but got
- "RobustZScore.learn_one expected univariate input, but got
- "RobustZScore.score_one expected univariate input, but got
- ZScore.score_one expected univariate input, but got
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/91795b6fe80ee783.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/python/apache_beam/ml/anomaly/detectors/zscore.py:92
stdev_tracker: Optional[StdevTracker] = None,
**kwargs):
if "threshold_criterion" not in kwargs:
kwargs["threshold_criterion"] = FixedThreshold(3)
super().__init__(**kwargs)
self._sub_stat_tracker = sub_stat_tracker or IncSlidingMeanTracker(
DEFAULT_WINDOW_SIZE)
self._stdev_tracker = stdev_tracker or IncSlidingStdevTracker(
DEFAULT_WINDOW_SIZE)
def learn_one(self, x: beam.Row) -> None:
"""Updates the mean and standard deviation trackers with a new data point.
Args:
x: A `beam.Row` containing a single numerical value.
"""
if len(x.__dict__) != 1:
raise ValueError(
"ZScore.learn_one expected univariate input, but got %s", str(x))
v = next(iter(x))
self._stdev_tracker.push(v)
self._sub_stat_tracker.push(v)
def score_one(self, x: beam.Row) -> Optional[float]:
"""Scores a data point using the Z-Score.
Args:
x: A `beam.Row` containing a single numerical value.
Returns:
float | None: The Z-Score.
"""
if len(x.__dict__) != 1:
raise ValueError(
"ZScore.score_one expected univariate input, but got %s", str(x))View on GitHub (pinned to 12126d8942)