pola-rs/polars · error

pyarrow is required for converting a pandas series to Polars

Error message

pyarrow is required for converting a pandas series to Polars, unless it is a simple numpy-backed one (e.g. 'int64', 'bool', 'float32' - not 'Int64')

What it means

pandas_to_pyseries has a fast path only for simple NumPy-backed pandas dtypes (plain int/bool/float, or object-of-str without NaN). Everything else — nullable 'Int64', 'string[python]', categorical, tz-aware datetimes — is routed through pyarrow; if pyarrow is not installed, polars raises this ImportError rather than producing wrong data.

Source

Thrown at py-polars/src/polars/_utils/construction/series.py:438

    dtype: PolarsDataType | None = None,
    *,
    strict: bool = True,
    nan_to_null: bool = True,
) -> PySeries:
    """Construct a PySeries from a pandas Series or DatetimeIndex."""
    if not name and values.name is not None:
        name = str(values.name)
    if is_simple_numpy_backed_pandas_series(values):
        return pl.Series(
            name, values.to_numpy(), dtype=dtype, nan_to_null=nan_to_null, strict=strict
        )._s
    if not _PYARROW_AVAILABLE:
        msg = (
            "pyarrow is required for converting a pandas series to Polars, "
            "unless it is a simple numpy-backed one "
            "(e.g. 'int64', 'bool', 'float32' - not 'Int64')"
        )
        raise ImportError(msg)
    return arrow_to_pyseries(
        name,
        plc.pandas_series_to_arrow(values, nan_to_null=nan_to_null),
        dtype=dtype,
        strict=strict,
    )


def arrow_to_pyseries(
    name: str,
    values: pa.Array,
    dtype: PolarsDataType | None = None,
    *,
    strict: bool = True,
    rechunk: bool = True,
) -> PySeries:
    """Construct a PySeries from an Arrow array."""
    array = plc.coerce_arrow(values)

View on GitHub (pinned to df599052da)

Solutions

  1. Install pyarrow: pip install pyarrow (or polars[pyarrow] extras where offered).
  2. Convert to a plain NumPy dtype at the boundary: s.astype("int64") / s.to_numpy() and wrap with pl.Series(...).
  3. Avoid pandas nullable/extension dtypes (Int64, string, boolean) when pyarrow is unavailable.

Example fix

// before
ps = pd.Series([1, 2], dtype="Int64")
s = pl.Series(ps)  # ImportError without pyarrow

// after
s = pl.Series(ps.to_numpy())  # or: pip install pyarrow
Defensive patterns

Strategy: validation

Validate before calling

import importlib.util

needs_arrow = str(ps.dtype) not in {"int64", "int32", "float64", "float32", "bool", "object"}
if needs_arrow and importlib.util.find_spec("pyarrow") is None:
    ps = ps.astype("int64") if "Int" in str(ps.dtype) else ps  # or raise with a clear message
s = pl.Series(ps)

Type guard

def is_simple_numpy_backed(ps: pd.Series) -> bool:
    return str(ps.dtype) in {"int64", "int32", "float64", "float32", "bool"} or (
        ps.dtype == "object" and not ps.hasnans and len(ps) and isinstance(ps.iloc[0], str)
    )

Try / catch

try:
    s = pl.Series(ps)
except ImportError as e:
    if "pyarrow is required" in str(e):
        s = pl.Series(ps.to_numpy())  # nullable metadata is lost; decide knowingly
    else:
        raise

Prevention

When it happens

Trigger: pl.from_pandas(pd.Series([1, 2], dtype="Int64")) with no pyarrow in the environment; converting pd.Series of pd.Timestamp or category dtype; pl.Series(pandas_series) with nullable dtypes.

Common situations: Slim deployment images (lambda, distroless) that omit pyarrow; dependency resolvers uninstalling pyarrow during a downgrade; notebooks where pyarrow was pip-removed to save space.

Related errors


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