apache/beam · error · WontImplementError

unstack() is not supported when using pandas < 1.2.0 Please…

Error message

unstack() is not supported when using pandas < 1.2.0
Please upgrade to pandas 1.2.0 or higher to use this operation.

What it means

DeferredFrame.unstack on a single-level index requires pandas >= 1.2.0. Older pandas' unstack behavior cannot be safely proxied by Beam's deferred expression machinery, so the wrapper hard-fails with a WontImplementError telling you to upgrade pandas.

Solutions

  1. Upgrade pandas: pip install -U 'pandas>=1.2.0' (check apache-beam's pandas compatibility range).
  2. Pin pandas>=1.2.0 in requirements.txt so runtime matches development.
  3. As a workaround on old pandas, move the unstack outside the pipeline (unstack after to_pandas()).

Example fix

# before
pandas==1.1.5
# after
pandas>=1.2.0
Defensive patterns

Strategy: validation

Validate before calling

import pandas as pd
if tuple(int(p) for p in pd.__version__.split('.')[:2]) < (1, 2):
    raise RuntimeError("pandas >= 1.2.0 required for Beam DataFrame unstack()")

Try / catch

from apache_beam.dataframe import frame_base
try:
    out = s.unstack()
except frame_base.WontImplementError:
    out = s.to_pandas().unstack()

Prevention

When it happens

Trigger: Calling unstack() on a DeferredSeries or DeferredDataFrame whose index has nlevels == 1 while the installed pandas version is below 1.2.0.

Common situations: Environments pinned to old pandas (e.g. Python 3.6-era requirements.txt); Beam deployments resolving an older pandas than the developer's local machine.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/c7069d0d99b3cef9. Report an issue: GitHub.

Appendix: source

Thrown at sdks/python/apache_beam/dataframe/frames.py:986

      def truncate(df):
        return df.truncate(before=before, after=after, axis=axis)

    return frame_base.DeferredFrame.wrap(
        expressions.ComputedExpression(
            'truncate',
            truncate, [self._expr],
            requires_partition_by=partitionings.Arbitrary(),
            preserves_partition_by=partitionings.Arbitrary()))

  @frame_base.with_docs_from(pd.DataFrame)
  @frame_base.args_to_kwargs(pd.DataFrame)
  @frame_base.populate_defaults(pd.DataFrame)
  def unstack(self, **kwargs):
    level = kwargs.get('level', -1)

    if self._expr.proxy().index.nlevels == 1:
      if PD_VERSION < (1, 2):
        raise frame_base.WontImplementError(
            "unstack() is not supported when using pandas < 1.2.0\n"
            "Please upgrade to pandas 1.2.0 or higher to use this operation.")
      return frame_base.DeferredFrame.wrap(
          expressions.ComputedExpression(
              'unstack', lambda s: s.unstack(**kwargs), [self._expr],
              requires_partition_by=partitionings.Index()))
    else:
      # Unstacking MultiIndex objects
      idx = self._expr.proxy().index

      # Converting level (int, str, or combination) to a list of number levels
      level_list = level if isinstance(level, list) else [level]
      level_number_list = [idx._get_level_number(l) for l in level_list]

      # Checking if levels provided are of CategoricalDtype
      if not all(isinstance(idx.levels[l].dtype, (pd.CategoricalDtype,
                                                  pd.BooleanDtype))
                 for l in level_number_list):

View on GitHub (pinned to 12126d8942)