pandas-dev/pandas · error · NotImplementedError

N-dimensional objects, where N > 2, are not supported with…

Error message

N-dimensional objects, where N > 2, are not supported with eval

What it means

Raised in Term._resolve_name when a referenced object has an integral ndim attribute greater than 2. The eval/query engine operates on scalars, Series (1-D), and DataFrames (2-D); higher-dimensional arrays (e.g. 3-D numpy ndarrays) cannot be aligned or broadcast by the evaluation machinery, so a NotImplementedError is raised at name-resolution time.

Solutions

  1. Flatten or reshape the array to <= 2 dimensions before referencing it: a = a.reshape(a.shape[0], -1).
  2. Convert the array to a DataFrame/Series first: df_a = pd.DataFrame(a); then query against df_a.
  3. Index into a single 2-D slice: pd.eval('@a[:,:,0] > 0') after extracting the slice into a separate local.
  4. Avoid eval/query for >2-D data; use numpy boolean masking directly: a[a > 0].

Example fix

// before
import numpy as np
a = np.zeros((4, 4, 4))
pd.eval("@a > 0")

// after
a2d = a.reshape(a.shape[0], -1)
pd.eval("@a2d > 0")
# or just
a > 0
Defensive patterns

Strategy: validation

Validate before calling

import numpy as np

def eval_safe_ndim(obj) -> bool:
    ndim = getattr(obj, 'ndim', None)
    return isinstance(ndim, int) and ndim <= 2

a = np.zeros((4,4,4))
assert eval_safe_ndim(a), 'cannot pass >2-D arrays to eval/query'

Type guard

import numpy as np

def is_eval_compatible(obj) -> bool:
    ndim = getattr(obj, 'ndim', None)
    if ndim is None:
        return True  # scalars are fine
    return isinstance(ndim, int) and ndim <= 2

Try / catch

try:
    pd.eval('@a > 0')
except NotImplementedError as e:
    if 'N-dimensional' in str(e):
        a2d = a.reshape(a.shape[0], -1)
        result = a > 0
    else:
        raise

Prevention

When it happens

Trigger: pd.eval('@a > 0') or df.query('@a') where the @-prefixed local 'a' is a numpy array with ndim >= 3 (e.g. np.zeros((2,2,2))). Also triggered by referencing a 3-D xarray.DataArray or stacked tensor stored in the calling frame's locals/globals.

Common situations: Passing multi-dimensional model outputs (image batches, time×channel×feature tensors) into a query expression expecting tabular data. Confusing a DataFrame.values (2-D) with a reshaped 3-D view. Pulling an ndarray from an .npz file and feeding it directly to eval.

Related errors


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

Appendix: source

Thrown at pandas/core/computation/ops.py:123

    def __call__(self, *args, **kwargs):
        return self.value

    def evaluate(self, *args, **kwargs) -> Term:
        return self

    def _resolve_name(self):
        local_name = str(self.local_name)
        is_local = self.is_local
        if local_name in self.env.scope and isinstance(
            self.env.scope[local_name], type
        ):
            is_local = False

        res = self.env.resolve(local_name, is_local=is_local)
        self.update(res)

        if hasattr(res, "ndim") and isinstance(res.ndim, int) and res.ndim > 2:
            raise NotImplementedError(
                "N-dimensional objects, where N > 2, are not supported with eval"
            )
        return res

    def update(self, value) -> None:
        """
        search order for local (i.e., @variable) variables:

        scope, key_variable
        [('locals', 'local_name'),
         ('globals', 'local_name'),
         ('locals', 'key'),
         ('globals', 'key')]
        """
        key = self.name

        # if it's a variable name (otherwise a constant)
        if isinstance(key, str):

View on GitHub (pinned to 3b7651241d)