pandas-dev/pandas · error · ValueError
'values' must be a NumPy array, not {type(values).__name__}
Error message
'values' must be a NumPy array, not {type(values).__name__} What it means
Raised by NumpyExtensionArray.__init__ when the `values` argument is neither an np.ndarray nor another NumpyExtensionArray. NumpyExtensionArray is the pandas ExtensionArray wrapper around a single NumPy ndarray, so it strictly requires a concrete ndarray backing store. Any other input (list, tuple, scalar, Series) is rejected at construction because the wrapper has no path to coerce it.
Source
Thrown at pandas/core/arrays/numpy_.py:128
# ExtensionBlock, search for `ABCNumpyExtensionArray`. We check for
# that _typ to ensure that users don't unnecessarily use EAs inside
# pandas internals, which turns off things like block consolidation.
_typ = "npy_extension"
__array_priority__ = 1000
_ndarray: np.ndarray
_dtype: NumpyEADtype
_internal_fill_value = np.nan
# ------------------------------------------------------------------------
# Constructors
def __init__(
self, values: np.ndarray | NumpyExtensionArray, copy: bool = False
) -> None:
if isinstance(values, type(self)):
values = values._ndarray
if not isinstance(values, np.ndarray):
raise ValueError(
f"'values' must be a NumPy array, not {type(values).__name__}"
)
if values.ndim == 0:
# Technically we support 2, but do not advertise that fact.
raise ValueError("NumpyExtensionArray must be 1-dimensional.")
if copy:
values = values.copy()
dtype = NumpyEADtype(values.dtype)
super().__init__(values, dtype)
@classmethod
def _from_sequence(
cls, scalars, *, dtype: Dtype | None = None, copy: bool = False
) -> NumpyExtensionArray:
if isinstance(dtype, NumpyEADtype):View on GitHub (pinned to 71959b8cb9)
Solutions
- Convert the input to an ndarray first: pd.arrays.NumpyExtensionArray(np.asarray(values)).
- Use the public factory pd.array(values) instead of the NumpyExtensionArray constructor directly.
- If the input is a list-like, wrap it with np.asarray(values, dtype=...) before passing.
Example fix
# before pd.arrays.NumpyExtensionArray([1, 2, 3]) # after pd.arrays.NumpyExtensionArray(np.asarray([1, 2, 3])) # or simply pd.array([1, 2, 3])
Defensive patterns
Strategy: type-guard
Validate before calling
import numpy as np
def to_numpy_ea(values):
if not isinstance(values, (np.ndarray, pd.arrays.NumpyExtensionArray)):
values = np.asarray(values)
return pd.arrays.NumpyExtensionArray(values) Type guard
import numpy as np
def is_ndarray_like(values) -> bool:
return isinstance(values, (np.ndarray, pd.arrays.NumpyExtensionArray)) Try / catch
try:
arr = pd.arrays.NumpyExtensionArray(values)
except ValueError:
arr = pd.arrays.NumpyExtensionArray(np.asarray(values)) Prevention
- Prefer pd.array(values) over the NumpyExtensionArray constructor; it accepts any array-like.
- Type-check inputs at API boundaries with isinstance(x, np.ndarray).
- Avoid subclassing NumpyExtensionArray without normalizing results to ndarray.
When it happens
Trigger: Directly constructing pd.arrays.NumpyExtensionArray(<not-an-ndarray>), e.g. passing a Python list, a tuple, a pandas Series, or a scalar value. Also triggered when subclassing NumpyExtensionArray (e.g. StringArray paths) and feeding a non-ndarray result back into type(self)(...).
Common situations: Developers reach for pd.arrays.NumpyExtensionArray by mistake instead of pd.array(...) or pd.Series(...). Passing raw Python lists or a Series into the class constructor. Refactoring code that previously used np.asarray-only paths.
Related errors
- NumpyExtensionArray must be 1-dimensional.
- Unsupported type '{type(values)}' for ArrowExtensionArray
- Invalid dtype {dtype} for PeriodArray
- Incorrect dtype
- dtype is not specified and cannot be inferred
AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07).
Data as JSON: /api/errors/ad959a71519d0bb8.
Report an issue: GitHub.