pola-rs/polars · error · NotImplementedError
non-dictionary categoricals are not yet supported
Error message
non-dictionary categoricals are not yet supported
What it means
Polars can only import categorical columns that are dictionary-encoded, i.e. describe_categorical()['is_dictionary'] is True. A producer reporting is_dictionary=False advertises a categorical without a categories dictionary, which has no Polars equivalent on the import path, so Polars raises NotImplementedError instead of guessing.
Source
Thrown at py-polars/src/polars/interchange/from_dataframe.py:150
data = pl.Series._from_buffers(String, data=data_buffers, validity=None)
# Add the validity buffer if present
validity_buffer = _construct_validity_buffer(
buffers["validity"], column, String, data, offset, allow_copy=allow_copy
)
if validity_buffer is not None:
data = pl.Series._from_buffers(
String, data=data_buffers, validity=validity_buffer
)
return data
def _categorical_column_to_series(column: Column, *, allow_copy: bool) -> Series:
categorical = column.describe_categorical
if not categorical["is_dictionary"]:
msg = "non-dictionary categoricals are not yet supported"
raise NotImplementedError(msg)
categories_col = categorical["categories"]
if categories_col.size() == 0:
dtype = Enum([])
elif categories_col.dtype[0] != DtypeKind.STRING:
msg = "non-string categories are not supported"
raise NotImplementedError(msg)
else:
categories = _string_column_to_series(categories_col, allow_copy=allow_copy)
dtype = Enum(categories)
buffers = column.get_buffers()
offset = column.offset
data_buffer = _construct_data_buffer(
*buffers["data"], column.size(), offset, allow_copy=allow_copy
)
validity_buffer = _construct_validity_buffer(View on GitHub (pinned to df599052da)
Solutions
- Change the producer to dictionary-encode the column and report is_dictionary=True
- Expose the column as plain string or integer data instead of categorical
- Convert the column upstream (e.g. cast to string in the source system) before interchange conversion
Defensive patterns
Strategy: validation
Validate before calling
def categorical_columns_are_dictionary_encoded(df) -> bool:
from polars.interchange.protocol import DtypeKind
proto = df.__dataframe__(allow_copy=False)
for col in proto.get_columns():
if col.dtype[0] == DtypeKind.CATEGORICAL:
if not col.describe_categorical()['is_dictionary']:
return False
return True Try / catch
try:
out = pl.from_dataframe(df)
except NotImplementedError as e:
if 'non-dictionary categoricals' in str(e):
# ask producer for plain strings or fix its encoding
raise
raise Prevention
- Producers: always dictionary-encode categorical columns and set is_dictionary=True
- Audit custom producers for categorical metadata correctness before shipping
- Prefer exporting categoricals as plain strings when in doubt - polars can re-encode them
When it happens
Trigger: Consuming a categorical column from a producer whose describe_categorical() returns is_dictionary=False.
Common situations: Custom producers exposing non-dictionary categorical systems; early adopters of extended interchange features; porting pandas.Categorical-like semantics where the mapping is implicit rather than dictionary-encoded.
Related errors
- non-string categories are not supported
- unsupported temporal data type: {dtype!r}
- `describe_categorical` only works on categorical columns
- cannot create String column without an offsets buffer
- data buffer must be cast from {data_dtype} to UInt32
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/1a0d987520002306.
Report an issue: GitHub.