pola-rs/polars · error · TypeError

expected pandas DataFrame or Series, got {qualified_type_nam

Error message

expected pandas DataFrame or Series, got {qualified_type_name(data)!r}

What it means

Raised by polars.from_pandas when the object passed as `data` is neither a pandas DataFrame nor a pandas Series. The function is the dedicated pandas bridge; after the pd.DataFrame/pd.Series isinstance checks fail, the final else branch reports the qualified type name of whatever was passed. It exists to stop silently mis-interpreting array-likes or other library objects through pandas conversion.

Source

Thrown at py-polars/src/polars/convert/general.py:729

    """
    if include_index and isinstance(data, pd.Series):
        data = data.reset_index()

    if isinstance(data, (pd.Series, pd.Index, pd.DatetimeIndex)):
        return wrap_s(pandas_to_pyseries("", data, nan_to_null=nan_to_null))
    elif isinstance(data, pd.DataFrame):
        return wrap_df(
            pandas_to_pydf(
                data,
                schema_overrides=schema_overrides,
                rechunk=rechunk,
                nan_to_null=nan_to_null,
                include_index=include_index,
            )
        )
    else:
        msg = f"expected pandas DataFrame or Series, got {qualified_type_name(data)!r}"
        raise TypeError(msg)


@dataclass(frozen=True, slots=True)
class _TablePatterns:
    """Format-specific regex patterns for table parsing."""

    cell_edge: re.Pattern[str]
    cell_split: re.Pattern[str]
    header_div: re.Pattern[str]
    row_div: re.Pattern[str]
    rstrip_chars: str


_TABLE_PATTERNS_CACHE: dict[TableRepr, _TablePatterns] = {}


def _build_table_patterns(table_repr: TableRepr) -> _TablePatterns:
    if table_repr is TableRepr.UTF8:

View on GitHub (pinned to df599052da)

Solutions

  1. If the data is a numpy array or dict of arrays, construct directly: pl.DataFrame(data) or pl.from_numpy(arr)
  2. If the data is Arrow (pyarrow.Table / RecordBatch / arrow_c_stream), use pl.from_arrow(data)
  3. If the data is genuinely pandas-like from another library (modin, cudf, duckdb relation .df()), convert to pandas first: pl.from_pandas(data.to_pandas()) or pl.from_pandas(data.df())
  4. Wrap non-iterable scalars in a container: pl.DataFrame({'col': [value]})

Example fix

# before
pl.from_pandas(np.array([[1, 2], [3, 4]]))

# after
pl.from_numpy(np.array([[1, 2], [3, 4]]))
Defensive patterns

Strategy: type-guard

Validate before calling

import pandas as pd

def to_polars_compat(data):
    if isinstance(data, (pd.DataFrame, pd.Series)):
        import polars as pl
        return pl.from_pandas(data)
    import polars as pl
    return pl.DataFrame(data)

Type guard

import pandas as pd
from typing import TypeGuard

def is_pandas_frame_or_series(data: object) -> TypeGuard[pd.DataFrame | pd.Series]:
    return isinstance(data, (pd.DataFrame, pd.Series))

Try / catch

try:
    df = pl.from_pandas(data)
except TypeError as e:
    raise TypeError(f'from_pandas got {type(data).__name__}; wrap or use pl.DataFrame/from_arrow') from e

Prevention

When it happens

Trigger: Calling pl.from_pandas() with a numpy ndarray, a plain Python list/dict, a pyarrow.Table, None, a pandas.Index, a modin/duckdb/pyspark object, or any non-pandas iterable. Any code path that reaches the else branch (not isinstance(data, pd.DataFrame)) with a non-Series raises.

Common situations: Migrating pandas code and swapping pd.DataFrame(...) for pl.from_pandas(...) without changing the input; passing an Arrow table or numpy matrix because both are 'table-like'; feeding a .to_numpy() result or a generator back in; version-agnostic helper functions that accept 'any data' and blindly call from_pandas.

Related errors


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