pola-rs/polars · error
pyarrow is required for converting a pandas dataframe to Pol
Error message
pyarrow is required for converting a pandas dataframe to Polars, unless each of its columns is a simple numpy-backed one (e.g. 'int64', 'bool', 'float32' - not 'Int64')
What it means
Converting a pandas DataFrame to Polars goes through pyarrow unless every column is a simple numpy-backed dtype that polars can read directly (int64, bool, float32, ...). Nullable/extension dtypes ('Int64', 'boolean'), 'category', timezone-aware datetimes, and object columns require the arrow path — so when pyarrow is not installed, this ImportError is raised, explicitly noting the numpy-only exception.
Source
Thrown at py-polars/src/polars/_utils/construction/dataframe.py:1120
return PyDataFrame.empty_with_height(data.shape[0])
if all(is_simple_numpy_backed_pandas_series(data[col]) for col in data.columns):
# Convert via NumPy directly, no PyArrow needed.
return pl.DataFrame(
{str(col): data[col].to_numpy() for col in data.columns},
schema=schema,
strict=strict,
schema_overrides=schema_overrides,
nan_to_null=nan_to_null,
)._df
if not _PYARROW_AVAILABLE:
msg = (
"pyarrow is required for converting a pandas dataframe to Polars, "
"unless each of its columns is a simple numpy-backed one "
"(e.g. 'int64', 'bool', 'float32' - not 'Int64')"
)
raise ImportError(msg)
arrow_dict = {}
length = data.shape[0]
if convert_index:
for idxcol in data.index.names:
arrow_dict[str(idxcol)] = plc.pandas_series_to_arrow(
# get_level_values accepts `int | str`
# but `index.names` returns `Hashable`
data.index.get_level_values(idxcol), # type: ignore[arg-type, unused-ignore]
nan_to_null=nan_to_null,
length=length,
)
for col_idx, col_data in data.items():
arrow_dict[str(col_idx)] = plc.pandas_series_to_arrow(
col_data, nan_to_null=nan_to_null, length=length
)
View on GitHub (pinned to df599052da)
Solutions
- Install pyarrow: `pip install pyarrow` (or declare the `polars[pandas]` extra)
- If pyarrow is truly impossible, cast every non-simple column to a numpy-backed dtype first: `df["a"] = df["a"].astype("int64")` (after fillna), `df["cat"] = df["cat"].astype(str)`, tz-naive via `dt.tz_localize(None)`
- Audit dtypes before conversion: `df.dtypes` — anything that is not a plain numpy dtype needs either casting or pyarrow
Example fix
# before
import pandas as pd, polars as pl
pdf = pd.DataFrame({"a": pd.array([1, None], dtype="Int64")})
pl.from_pandas(pdf) # ImportError: pyarrow is required for converting a pandas dataframe to Polars ...
# after (option 1)
# pip install pyarrow
pl.from_pandas(pdf)
# after (option 2 — cast to simple numpy dtype)
pdf["a"] = pdf["a"].fillna(0).astype("int64")
pl.from_pandas(pdf) Defensive patterns
Strategy: validation
Validate before calling
import importlib.util
import numpy as np
import pandas as pd
def simple_numpy_backed(df: pd.DataFrame) -> bool:
return all(isinstance(df[c].dtype, np.dtype) and df[c].dtype.kind in "biufcMm" for c in df.columns)
if not importlib.util.find_spec("pyarrow") and not simple_numpy_backed(df):
raise RuntimeError("install pyarrow or cast nullable/categorical/object columns to numpy dtypes") Type guard
import importlib.util
import numpy as np
import pandas as pd
def convertible_without_pyarrow(df: pd.DataFrame) -> bool:
"""True if every column is a plain numpy-backed dtype polars can read directly."""
return all(isinstance(df[c].dtype, np.dtype) for c in df.columns) and not any(
isinstance(df[c].dtype, pd.CategoricalDtype) for c in df.columns
)
def pyarrow_available() -> bool:
return importlib.util.find_spec("pyarrow") is not None Try / catch
try:
pldf = pl.from_pandas(df)
except ImportError as e:
if "pyarrow" not in str(e):
raise
df = df.convert_dtypes(dtype_backend="numpy") if hasattr(df, "convert_dtypes") else df
pldf = pl.from_pandas(df.astype({c: "int64" for c in df.select_dtypes("Int64")})) Prevention
- Install pyarrow (or the polars[pandas] extra) wherever pandas interop is used
- Audit df.dtypes before conversion; nullable Int64/boolean, category, and tz-aware dtypes all need pyarrow
- Normalize nullable/extension dtypes to numpy dtypes at ingestion time in pyarrow-free environments
When it happens
Trigger: `pl.from_pandas(df)` (or DataFrame(df)) without pyarrow installed while df contains pandas nullable dtypes ('Int64', 'boolean', 'string[python]'), 'category', tz-aware datetime64[ns, tz], or object columns; the same call succeeds without pyarrow only if every column is plain numpy-backed.
Common situations: Slim production images installing polars without extras; a merge/astype upstream silently changed a column from int64 to nullable Int64, breaking a previously working conversion; pandas code adopting nullable dtypes while the deployment never needed pyarrow before.
Related errors
- {pfx}{name} requires {self._module_name!r} module to be inst
- {prefix}'{module_name}'{suffix}. Please install using the co
- {min_err_prefix} {module_root} {min_version} or higher (foun
- gevent is required for using LazyFrame.collect_async(gevent=
- `orient` must be one of {'col', 'row', None}, got {orient!r}
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/1e51bb4672a1b8f4.
Report an issue: GitHub.