pola-rs/polars · error

cannot create DataFrame from zero-dimensional array

Error message

cannot create DataFrame from zero-dimensional array

What it means

numpy_to_pydf rejects NumPy arrays with ndim == 0 (shape ()). A zero-dimensional array is a bare scalar (e.g. np.float64(3.0)) and has neither rows nor columns, so it cannot back a DataFrame. Only 1D and 2D arrays are constructible.

Source

Thrown at py-polars/src/polars/_utils/construction/dataframe.py:1278

                    orient = "col"
                    n_columns = n_schema_cols
                else:
                    orient = "row"
                    n_columns = shape[1]

            elif orient == "row":
                n_columns = shape[1]
            elif orient == "col":
                n_columns = shape[0]
            else:
                msg = f"`orient` must be one of {{'col', 'row', None}}, got {orient!r}"
                raise ValueError(msg)
        else:
            if shape == ():
                msg = "cannot create DataFrame from zero-dimensional array"
            else:
                msg = f"cannot create DataFrame from array with more than two dimensions; shape = {shape}"
            raise ValueError(msg)

    if schema is not None and len(schema) != n_columns:
        if (n_schema_cols := len(schema)) != 1:
            msg = f"dimensions of `schema` ({n_schema_cols}) must match data dimensions ({n_columns})"
            raise ValueError(msg)
        n_columns = n_schema_cols

    column_names, schema_overrides = _unpack_schema(
        schema, schema_overrides=schema_overrides, n_expected=n_columns
    )

    # Convert data to series
    if structured_array:
        data_series = [
            pl.Series(
                name=series_name,
                values=data[record_name],
                dtype=schema_overrides.get(record_name),

View on GitHub (pinned to df599052da)

Solutions

  1. Wrap the scalar in a sequence: pl.DataFrame([value]) or pl.DataFrame({"col": [value]}).
  2. Normalize the input: np.atleast_1d(arr) before passing.
  3. If the value came from .item(), keep the original array or use [arr.item()] instead.

Example fix

// before
val = arr.sum()  # np.float64, shape ()
df = pl.DataFrame(val)

// after
df = pl.DataFrame({"total": [float(arr.sum())]})
// or: df = pl.DataFrame(np.atleast_1d(arr.sum()))
Defensive patterns

Strategy: validation

Validate before calling

arr = np.asarray(value)
if arr.ndim == 0:
    arr = np.atleast_1d(arr)  # or: value = [value]
df = pl.DataFrame(arr)

Type guard

def is_constructible_ndarray(arr: np.ndarray) -> bool:
    return 1 <= arr.ndim <= 2

Prevention

When it happens

Trigger: pl.DataFrame(np.float64(5)); pl.DataFrame(np.array(1.0)); passing the result of aggregations like np.asarray(df["a"].sum()) or a single cell extracted with .item() wrapped back into np.array.

Common situations: Reductions (arr.sum(), np.mean(...)) returning scalars that flow into generic conversion code; iterating over data of unknown shape where a scalar slips through instead of a length-1 sequence.

Related errors


AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16). Data as JSON: /api/errors/79fc562e9bdb9e6d. Report an issue: GitHub.