pandas-dev/pandas · error · ValueError

Lengths must match.

Error message

Lengths must match.

What it means

Raised inside the categorical comparison operator wrapper (_cat_compare_op) when `other` is a non-hashable list-like whose length differs from the Categorical's length. Pandas only allows length-mismatched comparisons when `other` is a hashable scalar (e.g. a tuple that is itself a category); otherwise element-wise comparison requires equal lengths.

Source

Thrown at pandas/core/arrays/categorical.py:137

    )

    from pandas import (
        DataFrame,
        Index,
        Series,
    )


def _cat_compare_op(op):
    opname = f"__{op.__name__}__"
    fill_value = op is operator.ne

    @unpack_zerodim_and_defer(opname)
    def func(self, other):
        hashable = is_hashable(other)
        if is_list_like(other) and len(other) != len(self) and not hashable:
            # in hashable case we may have a tuple that is itself a category
            raise ValueError("Lengths must match.")

        if not self.ordered:
            if opname in ["__lt__", "__gt__", "__le__", "__ge__"]:
                raise TypeError(
                    "Unordered Categoricals can only compare equality or not"
                )
        if isinstance(other, Categorical):
            # Two Categoricals can only be compared if the categories are
            # the same (maybe up to ordering, depending on ordered)

            msg = "Categoricals can only be compared if 'categories' are the same."
            if not self._categories_match_up_to_permutation(other):
                raise TypeError(msg)

            if not self.ordered and not self.categories.equals(other.categories):
                # both unordered and different order
                other_codes = recode_for_categories(
                    other.codes, other.categories, self.categories, copy=False

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Make `other` the same length as the Categorical, or reduce `other` to a single hashable scalar if you meant a per-element comparison to one value.
  2. If you intended set membership, use `cat.isin(other)` instead of `cat == other`.
  3. Align both sides through a DataFrame/Series index so lengths stay synchronized.

Example fix

# before
cat = pd.Categorical(['a', 'b', 'c'])
res = cat == ['a', 'b']
# after
cat = pd.Categorical(['a', 'b', 'c'])
res = cat == ['a', 'b', 'a']
Defensive patterns

Strategy: validation

Validate before calling

def safe_cat_compare(cat, other, op):
    import numpy as np
    from pandas.api.types import is_list_like, is_hashable
    if is_list_like(other) and not is_hashable(other) and len(other) != len(cat):
        raise ValueError(f"other len {len(other)} != cat len {len(cat)}")
    return op(cat, other)

Type guard

null

Try / catch

try:
    res = cat == other
except ValueError as e:
    if 'Lengths must match' in str(e):
        # align or scalarize `other`
        pass
    raise

Prevention

When it happens

Trigger: Comparing a Categorical against a list/Series/array of a different length, e.g. `cat < [1, 2]` where cat has 3 elements. Triggered by any of __lt__, __gt__, __le__, __ge__, __eq__, __ne__ when the right-hand side is list-like and not hashable.

Common situations: Joining/grouping then comparing a categorical column with a list whose derivation dropped entries; or passing a hand-built list of expected categories that doesn't match row count.

Related errors


AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07). Data as JSON: /api/errors/d2c1d1d257abc553. Report an issue: GitHub.