pola-rs/polars · error · ValueError

cannot parse numpy data type {dtype!r} into Polars data type

Error message

cannot parse numpy data type {dtype!r} into Polars data type

What it means

numpy_char_to_dtype maps a numpy dtype character code to a polars dtype using the (kind, itemsize) pair. String kinds 'U'/'S' map to String/Binary, but any other kind/itemsize combination missing from NUMPY_KIND_AND_ITEMSIZE_TO_DTYPE raises ValueError. The classic offender is float16 (kind 'f', itemsize 2), which polars has no dtype for.

Source

Thrown at py-polars/src/polars/datatypes/convert.py:330

        dtype.kind,
        dtype.itemsize,
    ) in DataTypeMappings.NUMPY_KIND_AND_ITEMSIZE_TO_DTYPE


def numpy_char_code_to_dtype(dtype_char: str) -> PolarsDataType:
    """Convert a numpy character dtype to a Polars dtype."""
    dtype = np.dtype(dtype_char)
    if dtype.kind == "U":
        return String
    elif dtype.kind == "S":
        return Binary
    try:
        return DataTypeMappings.NUMPY_KIND_AND_ITEMSIZE_TO_DTYPE[
            dtype.kind, dtype.itemsize
        ]
    except KeyError:  # pragma: no cover
        msg = f"cannot parse numpy data type {dtype!r} into Polars data type"
        raise ValueError(msg) from None


def maybe_cast(el: Any, dtype: PolarsDataType) -> Any:
    """Try casting a value to a value that is valid for the given Polars dtype."""
    # cast el if it doesn't match
    from polars._utils.convert import (
        datetime_to_int,
        timedelta_to_int,
    )

    time_unit: TimeUnit
    if isinstance(el, datetime):
        time_unit = getattr(dtype, "time_unit", "us")
        return datetime_to_int(el, time_unit)
    elif isinstance(el, timedelta):
        time_unit = getattr(dtype, "time_unit", "us")
        return timedelta_to_int(el, time_unit)

View on GitHub (pinned to df599052da)

Solutions

  1. Cast before conversion: arr = arr.astype(np.float32) (or np.float64), then pl.Series(arr)
  2. Convert half-precision data to float32 at load/export boundaries so float16 never reaches polars
  3. If bit-exact storage matters, view the data as UInt16 and reinterpret later

Example fix

# before
s = pl.Series(half_precision_array)  # ValueError: float16

# after
s = pl.Series(half_precision_array.astype(np.float32))
Defensive patterns

Strategy: validation

Validate before calling

import numpy as np

def is_polars_mappable_dtype(arr: np.ndarray) -> bool:
    d = arr.dtype
    if d.kind in 'US':
        return True
    if d.kind == 'f' and d.itemsize < 4:
        return False  # float16
    if d.kind == 'c':
        return False  # complex
    return d.kind in 'biu'

if not is_polars_mappable_dtype(arr):
    arr = arr.astype(np.float32)

Try / catch

try:
    s = pl.Series(arr)
except ValueError as e:
    if 'cannot parse numpy data type' in str(e):
        s = pl.Series(arr.astype(np.float64))
    else:
        raise

Prevention

When it happens

Trigger: Converting arrays with dtype np.float16 or other unmapped (kind, itemsize) pairs through constructor helpers that resolve numpy character dtypes, e.g. pl.Series(model_output) where the array is half precision.

Common situations: Machine-learning pipelines: float16 activations/weights from PyTorch, ONNX, or TensorFlow; memory-saving half-precision columns read from disk; GPU-produced arrays.

Related errors


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