pandas-dev/pandas · error · NotImplementedError

> 1 ndim Categorical are not supported at this time

Error message

> 1 ndim Categorical are not supported at this time

What it means

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.

Solutions

  1. Flatten or select a single column: `pd.Categorical(arr[:, 0])` or `pd.Categorical(arr.ravel())` if a 1-D view is meaningful.
  2. Apply `astype('category')` per-column: `df.apply(lambda s: s.astype('category'))`.
  3. Reshape the input to 1-D with `.reshape(-1)` only if the data is genuinely 1-D stored in a higher-rank container.
  4. Verify `arr.ndim == 1` before construction as a guard.

Example fix

# before
import numpy as np
import pandas as pd
arr = np.array([['a', 'b'], ['c', 'd']])
cat = pd.Categorical(arr)  # NotImplementedError

# after (per column)
cats = [pd.Categorical(arr[:, j]) for j in range(arr.shape[1])]
Defensive patterns

Strategy: validation

Validate before calling

import numpy as np

def ensure_1d(values):
    if isinstance(values, np.ndarray) and values.ndim > 1:
        raise ValueError(f"expected 1-D input, got shape {values.shape}")
    return values

Type guard

def is_one_dimensional(values) -> bool:
    return not (hasattr(values, 'ndim') and values.ndim > 1)

Try / catch

try:
    cat = pd.Categorical(arr)
except NotImplementedError as e:
    if 'ndim' in str(e) and getattr(arr, 'ndim', 0) > 1:
        cat = pd.Categorical(arr.ravel())
    else:
        raise

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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

Appendix: source

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

        # sanitize input
        vdtype = getattr(values, "dtype", None)
        if isinstance(vdtype, CategoricalDtype):
            if dtype.categories is None:
                dtype = CategoricalDtype(values.categories, dtype.ordered)
        elif isinstance(values, range):
            from pandas.core.indexes.range import RangeIndex

            values = RangeIndex(values)
        elif not isinstance(values, (ABCIndex, ABCSeries, ExtensionArray)):
            values = com.convert_to_list_like(values)
            if isinstance(values, list) and len(values) == 0:
                # By convention, empty lists result in object dtype:
                values = np.array([], dtype=object)
            elif isinstance(values, np.ndarray):
                if values.ndim > 1:
                    # preempt sanitize_array from raising ValueError
                    raise NotImplementedError(
                        "> 1 ndim Categorical are not supported at this time"
                    )
                values = sanitize_array(values, None)
            else:
                # i.e. must be a list
                arr = sanitize_array(values, None)
                null_mask = isna(arr)
                if null_mask.any():
                    # We remove null values here, then below will re-insert
                    #  them, grep "full_codes"
                    arr_list = [values[idx] for idx in np.where(~null_mask)[0]]

                    # GH#44900 Do not cast to float if we have only missing values
                    if arr_list or arr.dtype == "object":
                        sanitize_dtype = None
                    else:
                        sanitize_dtype = arr.dtype

View on GitHub (pinned to 3b7651241d)