pandas-dev/pandas · error · ValueError

items in new_categories are not the same as in old…

Error message

items in new_categories are not the same as in old categories

What it means

Raised by `reorder_categories` when `new_categories` either has a different length than the current categories or contains values not present in the current categories. `reorder_categories` is strictly a permutation — the set of labels must be identical, only their order may change.

Solutions

  1. Use `set_categories(new_list, ordered=...)` when the membership legitimately changes.
  2. Pass the same set of categories in the desired order: build `new_categories` as a permutation of `list(cat.categories)`.
  3. Sort the current categories to derive the new order safely: `cat.reorder_categories(sorted(cat.categories), ordered=True)`.
  4. Validate `set(new_categories) == set(cat.categories)` and `len` equality before calling.

Example fix

# before
cat = pd.Categorical(['a', 'b', 'c'], categories=['a', 'b', 'c'])
cat = cat.reorder_categories(['a', 'b', 'd'])  # ValueError

# after (true reorder)
cat = cat.reorder_categories(['c', 'b', 'a'], ordered=True)
# after (intentionally changing membership)
cat = cat.set_categories(['a', 'b', 'd'])
Defensive patterns

Strategy: validation

Validate before calling

def safe_reorder(cat, new_categories, ordered=None):
    new_set = set(new_categories)
    if new_set != set(cat.categories) or len(new_categories) != len(cat.categories):
        return cat.set_categories(new_categories, ordered=ordered)
    return cat.reorder_categories(new_categories, ordered=ordered)

Type guard

def is_permutation_of_categories(cat, new_categories) -> bool:
    new = list(new_categories)
    return len(new) == len(cat.categories) and set(new) == set(cat.categories)

Try / catch

try:
    cat = cat.reorder_categories(new_list)
except ValueError as e:
    if 'not the same' in str(e):
        cat = cat.set_categories(new_list)
    else:
        raise

Prevention

When it happens

Trigger: `cat.reorder_categories(['a', 'b', 'd'])` on a Categorical whose categories are `['a', 'b', 'c']`, or any call that adds/drops a label rather than reordering.

Common situations: Confusing reorder with set/add/remove; datasets whose categories shifted between runs; calling reorder with a list built from a different column.

Related errors


AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11). Data as JSON: /api/errors/5f84a4b62f5cebc3. Report an issue: GitHub.

Appendix: source

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

        3   a
        dtype: category
        Categories (3, str): ['c' < 'b' < 'a']

        For :class:`pandas.CategoricalIndex`:

        >>> ci = pd.CategoricalIndex(["a", "b", "c", "a"])
        >>> ci
        CategoricalIndex(['a', 'b', 'c', 'a'], categories=['a', 'b', 'c'],
                         ordered=False, dtype='category')
        >>> ci.reorder_categories(["c", "b", "a"], ordered=True)
        CategoricalIndex(['a', 'b', 'c', 'a'], categories=['c', 'b', 'a'],
                         ordered=True, dtype='category')
        """
        if (
            len(self.categories) != len(new_categories)
            or not self.categories.difference(new_categories).empty
        ):
            raise ValueError(
                "items in new_categories are not the same as in old categories"
            )
        return self.set_categories(new_categories, ordered=ordered)

    def add_categories(self, new_categories) -> Self:
        """
        Add new categories.

        `new_categories` will be included at the last/highest place in the
        categories and will be unused directly after this call.

        Parameters
        ----------
        new_categories : category or list-like of category
            The new categories to be included.

        Returns
        -------

View on GitHub (pinned to 3b7651241d)