pandas-dev/pandas · error · TypeError

pd.api.extensions.take requires a numpy.ndarray…

Error message

pd.api.extensions.take requires a numpy.ndarray, ExtensionArray, Index, Series, or NumpyExtensionArray got {type(arr).__name__}.

What it means

pd.api.extensions.take() is a public utility for pandas-style array indexing (supporting negative indices and fill-value semantics). It only accepts numpy.ndarray, ExtensionArray, Index, Series, or NumpyExtensionArray as the source array. This guard (GH#52981) rejects Python lists, tuples, sets, and other non-array-like inputs early, before they reach the internal take_nd logic where they would fail with a less clear error.

Solutions

  1. Convert the input to np.asarray() first: pd.api.extensions.take(np.asarray(data), indices).
  2. Wrap in pd.Series(): pd.api.extensions.take(pd.Series(data), indices).
  3. Use the type the function expects by construction — build your data as np.ndarray from the start.

Example fix

# before
pd.api.extensions.take([10, 20, 30], [0, 0, -1])

# after
pd.api.extensions.take(np.array([10, 20, 30]), [0, 0, -1])
Defensive patterns

Strategy: validation

Validate before calling

def safe_take(arr, indices, **kwargs):
    if not isinstance(arr, (np.ndarray, pd.Series, pd.Index, pd.api.extensions.ExtensionArray)):
        arr = np.asarray(arr)
    return pd.api.extensions.take(arr, indices, **kwargs)

Type guard

def is_takeable(arr) -> bool:
    return isinstance(
        arr,
        (np.ndarray, pd.Series, pd.Index, pd.api.extensions.ExtensionArray)
    )

Try / catch

try:
    result = pd.api.extensions.take(data, indices)
except TypeError as e:
    if "requires a numpy.ndarray" in str(e):
        result = pd.api.extensions.take(np.asarray(data), indices)
    else:
        raise

Prevention

When it happens

Trigger: Calling pd.api.extensions.take([1, 2, 3], [0, 1]) with a plain Python list instead of an ndarray. Passing a tuple, set, or custom iterable as the first argument. Using a dictionary or scalar where an array is expected.

Common situations: Using pd.api.extensions.take as a safer alternative to numpy.take and forgetting to convert a list to an array. Passing data from JSON deserialization (which yields lists) directly without conversion. Interfacing with libraries that return Python lists rather than numpy arrays.

Related errors


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

Appendix: source

Thrown at pandas/core/algorithms.py:1374

    >>> pd.api.extensions.take(np.array([10, 20, 30]), [0, 0, -1])
    array([10, 10, 30])

    Setting ``allow_fill=True`` will place `fill_value` in those positions.

    >>> pd.api.extensions.take(np.array([10, 20, 30]), [0, 0, -1], allow_fill=True)
    array([10., 10., nan])

    >>> pd.api.extensions.take(
    ...     np.array([10, 20, 30]), [0, 0, -1], allow_fill=True, fill_value=-10
    ... )
    array([ 10,  10, -10])
    """
    if not isinstance(
        arr,
        (np.ndarray, ABCExtensionArray, ABCIndex, ABCSeries, ABCNumpyExtensionArray),
    ):
        # GH#52981
        raise TypeError(
            "pd.api.extensions.take requires a numpy.ndarray, ExtensionArray, "
            f"Index, Series, or NumpyExtensionArray got {type(arr).__name__}."
        )

    indices = ensure_platform_int(indices)

    if allow_fill:
        # Pandas style, -1 means NA
        validate_indices(indices, arr.shape[axis])
        # error: Argument 1 to "take_nd" has incompatible type
        # "ndarray[Any, Any] | ExtensionArray | Index | Series"; expected
        # "ndarray[Any, Any]"
        result = take_nd(
            arr,  # type: ignore[arg-type]
            indices,
            axis=axis,
            allow_fill=True,
            fill_value=fill_value,

View on GitHub (pinned to 3b7651241d)