{"record":{"id":"c0c43ffd8ef8cb39","repo":"pandas-dev/pandas","slug":"new-categories-need-to-have-the-same-number-of-ite","errorCode":null,"errorMessage":"new categories need to have the same number of items as the old categories!","messagePattern":"new categories need to have the same number of items as the old categories!","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/categorical.py","lineNumber":987,"sourceCode":"        >>> c\n        ['a', 'b']\n        Categories (2, str): ['a', 'b']\n\n        >>> c._set_categories(pd.Index([\"a\", \"c\"]))\n        >>> c\n        ['a', 'c']\n        Categories (2, str): ['a', 'c']\n        \"\"\"\n        if fastpath:\n            new_dtype = CategoricalDtype._from_fastpath(categories, self.ordered)\n        else:\n            new_dtype = CategoricalDtype(categories, ordered=self.ordered)\n        if (\n            not fastpath\n            and self.dtype.categories is not None\n            and len(new_dtype.categories) != len(self.dtype.categories)\n        ):\n            raise ValueError(\n                \"new categories need to have the same number of \"\n                \"items as the old categories!\"\n            )\n\n        super().__init__(self._ndarray, new_dtype)\n\n    def _set_dtype(self, dtype: CategoricalDtype, *, copy: bool) -> Self:\n        \"\"\"\n        Internal method for directly updating the CategoricalDtype\n\n        Parameters\n        ----------\n        dtype : CategoricalDtype\n\n        Notes\n        -----\n        We don't do any validation here. It's assumed that the dtype is\n        a (valid) instance of `CategoricalDtype`.","sourceCodeStart":969,"sourceCodeEnd":1005,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/arrays/categorical.py#L969-L1005","documentation":"Raised by the internal _set_categories (invoked by the `.categories` property setter) when the new categories list has a different length than the current categories. Renaming via the setter requires a 1:1 replacement; adding/removing categories changes the code mapping and must use the dedicated methods.","triggerScenarios":"`cat.categories = ['x','y','z']` when the current categories have 2 (or 4) entries. The setter delegates to _set_categories which enforces equal length.","commonSituations":"Renaming categories but accidentally dropping or adding one; chaining operations that change category count then assigning back via `.categories`.","solutions":["To rename in place, supply exactly len(cat.categories) new labels: `cat.categories = ['x','y']` (match count).","To add categories use `cat = cat.add_categories([...])`.","To remove use `cat = cat.remove_categories([...])` or `remove_unused_categories()`.","To fully replace use `cat = cat.set_categories([...])`."],"exampleFix":"# before\ncat = pd.Categorical(['a','b'], categories=['a','b'])\ncat.categories = ['x', 'y', 'z']\n# after\ncat = pd.Categorical(['a','b'], categories=['a','b'])\ncat.categories = ['x', 'y']","handlingStrategy":"validation","validationCode":"def safe_set_categories(cat, new_categories):\n    if len(new_categories) != len(cat.categories):\n        raise ValueError(f\"expected {len(cat.categories)} categories, got {len(new_categories)}\")\n    cat.categories = new_categories\n    return cat","typeGuard":"def same_category_count(cat, new_categories) -> bool:\n    return len(new_categories) == len(cat.categories)","tryCatchPattern":"try:\n    cat.categories = new_cats\nexcept ValueError as e:\n    if 'same number of items' in str(e):\n        cat = cat.set_categories(new_cats)\n    else:\n        raise","preventionTips":["Use the .categories setter only for 1:1 renames.","Use add_categories/remove_categories/set_categories for membership changes.","Verify len(new) == len(cat.categories) before assigning."],"tags":["categorical","categories-setter","length-mismatch","valueerror"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}