{"record":{"id":"32e1401cb2e9e03c","repo":"pandas-dev/pandas","slug":"cannot-set-a-categorical-with-another-without-ide","errorCode":null,"errorMessage":"Cannot set a Categorical with another, without identical categories","messagePattern":"Cannot set a Categorical with another, without identical categories","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/categorical.py","lineNumber":2465,"sourceCode":"            result = f\"{body}\\n{footer}\"\n        else:\n            # In the empty case we use a comma instead of newline to get\n            #  a more compact __repr__\n            body = \"[]\"\n            result = f\"{body}, {footer}\"\n\n        return result\n\n    # ------------------------------------------------------------------\n\n    def _validate_listlike(self, value):\n        # NB: here we assume scalar-like tuples have already been excluded\n        value = extract_array(value, extract_numpy=True)\n\n        # require identical categories set\n        if isinstance(value, Categorical):\n            if self.dtype != value.dtype:\n                raise TypeError(\n                    \"Cannot set a Categorical with another, \"\n                    \"without identical categories\"\n                )\n            # dtype equality implies categories_match_up_to_permutation\n            value = self._encode_with_my_categories(value)\n            return value._codes\n\n        from pandas import Index\n\n        # tupleize_cols=False for e.g. test_fillna_iterable_category GH#41914\n        to_add = Index._with_infer(value, tupleize_cols=False, copy=False).difference(\n            self.categories\n        )\n\n        # no assignments of values not in categories, but it's always ok to set\n        # something to np.nan\n        if len(to_add) and not isna(to_add).all():\n            raise TypeError(","sourceCodeStart":2447,"sourceCodeEnd":2483,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/core/arrays/categorical.py#L2447-L2483","documentation":"Raised in Categorical._validate_listlike when assigning a Categorical value into another Categorical whose dtype (categories + ordered flag) differs. dtype equality is required because categorical semantics are tied to the exact category set; a mismatch would silently re-encode values to wrong codes. Only categoricals with identical dtype can be assigned directly.","triggerScenarios":"cat1[0:3] = cat2 where cat1 and cat2 have different categories or different ordered flag. df.loc[i, 'catcol'] = other_cat_series with a different category set. fillna with a Categorical whose categories differ. Setting a slice via .iloc/.loc with a mismatched categorical right-hand side.","commonSituations":"Two columns were independently astype('category') and end up with category sets that differ by one entry. Merging data from sources where categories were defined separately. Trying to copy values between train/test splits where one side has extra categories.","solutions":["Align categories first: df['col'] = df['col'].cat.set_categories(other.cat.categories) (and match ordered) before assigning.","Use union_categoricals or pd.concat to build a shared dtype, then assign.","Convert the source to plain values (.astype(object).values or .to_numpy()) if category alignment is not desired.","Define a single CategoricalDtype up front and apply it to both sides with astype(shared_dtype)."],"exampleFix":"# before\nc1 = pd.Categorical(['a','b'], categories=['a','b','c'])\nc2 = pd.Categorical(['x'], categories=['x','y'])\nc1[0] = c2[0]  # TypeError\n\n# after\nshared = pd.CategoricalDtype(['a','b','c','x','y'], ordered=False)\nc1 = pd.Categorical(['a','b'], dtype=shared)\nc2 = pd.Categorical(['x'], dtype=shared)\nc1[0] = c2[0]","handlingStrategy":"validation","validationCode":"if isinstance(src, pd.Categorical) and isinstance(dst, pd.Categorical):\n    if src.dtype != dst.dtype:\n        src = src.astype(dst.dtype)\ndst[0:len(src)] = src","typeGuard":"def categories_compatible(a: pd.Categorical, b: pd.Categorical) -> bool:\n    return a.dtype == b.dtype","tryCatchPattern":"try:\n    target[mask] = source\nexcept TypeError as e:\n    if 'identical categories' in str(e):\n        target = target.cat.set_categories(source.cat.categories)\n        target[mask] = source\n    else:\n        raise","preventionTips":["Define a single shared CategoricalDtype and astype all columns to it before joins/assignments.","After pd.concat or merge, re-apply the canonical dtype to categorical columns."],"tags":["categorical","setitem","dtype-mismatch","categories"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}