{"record":{"id":"bd6b04f0352bc0fb","repo":"pandas-dev/pandas","slug":"1-ndim-categorical-are-not-supported-at-this-tim","errorCode":null,"errorMessage":"> 1 ndim Categorical are not supported at this time","messagePattern":"> 1 ndim Categorical are not supported at this time","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/categorical.py","lineNumber":435,"sourceCode":"\n        # sanitize input\n        vdtype = getattr(values, \"dtype\", None)\n        if isinstance(vdtype, CategoricalDtype):\n            if dtype.categories is None:\n                dtype = CategoricalDtype(values.categories, dtype.ordered)\n        elif isinstance(values, range):\n            from pandas.core.indexes.range import RangeIndex\n\n            values = RangeIndex(values)\n        elif not isinstance(values, (ABCIndex, ABCSeries, ExtensionArray)):\n            values = com.convert_to_list_like(values)\n            if isinstance(values, list) and len(values) == 0:\n                # By convention, empty lists result in object dtype:\n                values = np.array([], dtype=object)\n            elif isinstance(values, np.ndarray):\n                if values.ndim > 1:\n                    # preempt sanitize_array from raising ValueError\n                    raise NotImplementedError(\n                        \"> 1 ndim Categorical are not supported at this time\"\n                    )\n                values = sanitize_array(values, None)\n            else:\n                # i.e. must be a list\n                arr = sanitize_array(values, None)\n                null_mask = isna(arr)\n                if null_mask.any():\n                    # We remove null values here, then below will re-insert\n                    #  them, grep \"full_codes\"\n                    arr_list = [values[idx] for idx in np.where(~null_mask)[0]]\n\n                    # GH#44900 Do not cast to float if we have only missing values\n                    if arr_list or arr.dtype == \"object\":\n                        sanitize_dtype = None\n                    else:\n                        sanitize_dtype = arr.dtype\n","sourceCodeStart":417,"sourceCodeEnd":453,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/core/arrays/categorical.py#L417-L453","documentation":"Raised in `Categorical.__init__` when the input values is a numpy ndarray with `ndim > 1`. Categoricals are strictly 1-D; multi-dimensional data has no defined category layout, so pandas preemptively rejects it before `sanitize_array` would raise a less informative error.","triggerScenarios":"Passing a 2-D numpy array or a DataFrame's `.values` of shape `(n, m)` directly to `pd.Categorical(...)` or `.astype('category')` on a DataFrame.","commonSituations":"Calling `.astype('category')` on a whole DataFrame instead of per-column; reshaping pipelines that accidentally keep an extra dimension; Tensor/array interop code that hands off 2-D arrays.","solutions":["Flatten or select a single column: `pd.Categorical(arr[:, 0])` or `pd.Categorical(arr.ravel())` if a 1-D view is meaningful.","Apply `astype('category')` per-column: `df.apply(lambda s: s.astype('category'))`.","Reshape the input to 1-D with `.reshape(-1)` only if the data is genuinely 1-D stored in a higher-rank container.","Verify `arr.ndim == 1` before construction as a guard."],"exampleFix":"# before\nimport numpy as np\nimport pandas as pd\narr = np.array([['a', 'b'], ['c', 'd']])\ncat = pd.Categorical(arr)  # NotImplementedError\n\n# after (per column)\ncats = [pd.Categorical(arr[:, j]) for j in range(arr.shape[1])]","handlingStrategy":"validation","validationCode":"import numpy as np\n\ndef ensure_1d(values):\n    if isinstance(values, np.ndarray) and values.ndim > 1:\n        raise ValueError(f\"expected 1-D input, got shape {values.shape}\")\n    return values","typeGuard":"def is_one_dimensional(values) -> bool:\n    return not (hasattr(values, 'ndim') and values.ndim > 1)","tryCatchPattern":"try:\n    cat = pd.Categorical(arr)\nexcept NotImplementedError as e:\n    if 'ndim' in str(e) and getattr(arr, 'ndim', 0) > 1:\n        cat = pd.Categorical(arr.ravel())\n    else:\n        raise","preventionTips":["Check `arr.ndim == 1` before constructing a Categorical from an ndarray.","Apply `.astype('category')` to Series/DataFrame columns, never to a 2-D DataFrame directly.","In tensor/array interop, squeeze or select a column before passing to pandas."],"tags":["categorical","constructor","ndim","notimplementederror"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}