pandas-dev/pandas · error · ValueError

codes need to be array-like integers

Error message

codes need to be array-like integers

What it means

Raised by _validate_codes_for_dtype when the codes array, after conversion to a numpy array, has a dtype whose kind is not integer ('i' or 'u'). Codes must be integer positions into the categories array; float or object codes (e.g. [0.0, 1.0] or ['0','1']) are rejected.

Source

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

            fill_value = self._unbox_scalar(fill_value)
        else:
            raise TypeError(
                "Cannot setitem on a Categorical with a new "
                f"category ({fill_value}), set the categories first"
            ) from None
        return fill_value

    @classmethod
    def _validate_codes_for_dtype(cls, codes, *, dtype: CategoricalDtype) -> np.ndarray:
        if isinstance(codes, ExtensionArray) and is_integer_dtype(codes.dtype):
            # Avoid the implicit conversion of Int to object
            if isna(codes).any():
                raise ValueError("codes cannot contain NA values")
            codes = codes.to_numpy(dtype=np.int64)
        else:
            codes = np.asarray(codes)
        if len(codes) and codes.dtype.kind not in "iu":
            raise ValueError("codes need to be array-like integers")

        if len(codes) and (codes.max() >= len(dtype.categories) or codes.min() < -1):
            raise ValueError("codes need to be between -1 and len(categories)-1")
        return codes

    # -------------------------------------------------------------

    @ravel_compat
    def __array__(
        self, dtype: NpDtype | None = None, copy: bool | None = None
    ) -> np.ndarray:
        """
        The numpy array interface.

        Users should not call this directly. Rather, it is invoked by
        :func:`numpy.array` and :func:`numpy.asarray`.

        Parameters

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Cast codes to int first: `pd.Categorical.from_codes(np.asarray(codes).astype(np.int64), categories=[...])`.
  2. Ensure the source produces integer dtype (e.g. `.astype('int64')` after rounding/filling NA).
  3. If codes are non-integer labels, use the regular `pd.Categorical(values)` constructor instead of from_codes.

Example fix

# before
pd.Categorical.from_codes([0.0, 1.0, 0.0], categories=['a','b'])
# after
import numpy as np
pd.Categorical.from_codes(np.asarray([0.0, 1.0, 0.0]).astype(np.int64), categories=['a','b'])
Defensive patterns

Strategy: validation

Validate before calling

import numpy as np

def to_int_codes(codes):
    arr = np.asarray(codes)
    if arr.dtype.kind not in 'iu':
        arr = arr.astype(np.int64)
    return arr

# usage: pd.Categorical.from_codes(to_int_codes(codes), categories=cats)

Type guard

def is_integer_codes(codes) -> bool:
    import numpy as np
    arr = np.asarray(codes)
    return arr.dtype.kind in 'iu'

Try / catch

try:
    cat = pd.Categorical.from_codes(codes, categories=cats)
except ValueError as e:
    if 'array-like integers' in str(e):
        import numpy as np
        cat = pd.Categorical.from_codes(np.asarray(codes).astype(np.int64), categories=cats)
    else:
        raise

Prevention

When it happens

Trigger: `pd.Categorical.from_codes([0.0, 1.0, 0.0], categories=['a','b'])` (float codes), or codes as strings. Only triggers when the array is non-empty; empty codes are allowed.

Common situations: Receiving codes from a JSON/CSV that parsed them as floats; downstream math that produced float arrays; mixing Int64 (handled above) vs plain float.

Related errors


AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07). Data as JSON: /api/errors/abe0729786a3c792. Report an issue: GitHub.