Polars Knowledge Patch
Use this skill when writing, reviewing, debugging, or migrating Polars code in
Python, Rust, or SQL. Check the project's pinned Polars version first and apply
only guidance relevant to that version. Prefer the project's schema, code, and
tests when they establish behavior more directly.
Reference index
| Reference |
Topics |
data-types-and-expressions.md |
Construction, dtypes, nested data, expressions, aggregation, temporal behavior |
io-and-serialization.md |
Parquet, Arrow, CSV, Excel, databases, cloud storage, serialization |
lazy-execution-and-joins.md |
Lazy schemas, optimizations, streaming, joins, grouping, sinks |
migration-and-deprecations.md |
Breaking defaults, renamed APIs, deprecations, exceptions, runtime support |
sql.md |
SQL operators, functions, aggregates, joins, validation, frame scope |
Migration triage
When upgrading an existing application, check these high-impact changes first:
Make row orientation explicit when constructing heterogeneous frames:
pl.DataFrame([[1, "a"], [2, "b"]], orient="row")
Expect inferred Series construction to be strict. Use strict=False only
when common-dtype inference or casting is intentional.
Replace dtype-changing replace calls with replace_strict; supply a
default when unmapped values must survive.
Read serialized frames with deserialize, not read_json. Default
serialization is binary; request format="json" explicitly for JSON.
Audit Parquet path behavior. Directories enable Hive partitioning by default,
while files, globs, and file lists do not.
Replace repeated lazy metadata access with one collect_schema() call.
Review SQL integer division: / uses true division and may return fractions.
Remove reliance on implicit optimization in map_batches; its default is no
optimizer transformations.
Construction and schema
Build frames and series deliberately
- A zoned datetime dtype converts input values into its zone. It does not merely
replace time-zone metadata, so naive wall-clock values may shift.
- Two-dimensional NumPy input and
Series.reshape produce fixed-size Array
values. Convert with .arr.to_list() when callers require List.
- Byte scalars in a
DataFrame constructor broadcast across rows.
- Empty JSON construction preserves its schema.
- Duplicate names in an Arrow table, and duplicate names in a Parquet file,
raise
DuplicateError.
- Use
LazyFrame.match_to_schema(...) to reconcile a lazy input with an expected
schema before execution.
Treat nested conversion as strict
strict=True validates conversions inside nested values, not only the outer
dtype. Align Enum category sets before appending; appending no longer merges
different category definitions.
For nested queries and transformations:
list.contains and arr.contains accept nulls_equal.
- List and Array
any/all accept ignore_nulls.
- List and Array support
is_unique.
- Fixed-size Array columns can be grouping keys.
list.slice broadcasts scalar input across rows.
Expression behavior
Handle nulls explicitly
- EWM mean, standard deviation, and variance preserve input null positions. Add
.forward_fill() only when reproducing the earlier filled result.
- The initial unbiased
ewm_var and ewm_std value is null.
- A null
clip bound leaves the original value unchanged.
fill_null operates on columns whose dtype is Null.
- Rolling-by expressions propagate nullness from their
by column.
Update selection and replacement code
pl.nth positional arguments are indices. Use pl.col("a").get(1) to select
an element from a named expression.
get and gather raise for out-of-bounds indices unless
null_on_oob=True is passed.
Series.equals ignores names unless check_names=True.
replace_strict supports Enum values and raises for unmapped non-null input
when no default is supplied.
Check changed numerical results
- Decimal sums widen result precision and raise instead of wrapping on overflow.
- Covariance with a constant returns zero rather than
NaN.
rolling_corr ignores its deprecated ddof argument.
- Globally seeded sampling is reproducible because
sample() honors the global
random seed.
- Datetime truncation is epoch-aligned; weekly buckets remain Monday-aligned.
Lazy execution and streaming
Collect schemas once
Access to LazyFrame.schema, .dtypes, .columns, and .width can trigger an
expensive schema resolution and warns accordingly. Prefer:
schema = lf.collect_schema()
names = schema.names()
Use QueryOptFlags when customizing lazy optimization. Persisted expressions or
plans must use a DSL representation compatible with the reader; incompatible
representations are rejected.
Use the streaming engine as supported execution
The streaming engine is stable and supports a broad set of operations, including
additional group-by aggregations, grouped as-of joins, native interpolation,
format-inferred strptime, covariance/correlation, PyArrow dataset sources, and
Parquet sinks. Grouped as-of joins preserve null rows.
Callback sinks can write cloud targets, and external object_store
implementations can add schemes beyond the native set. Configure
POLARS_OOC_DISK_BUDGET_MB to bound disk space for out-of-core spilling.
I/O checkpoints
Parquet and Arrow
- Unprojected Parquet columns are not dtype-validated during projected reads.
- Use
scan_parquet(..., cast_options=...) to control scan-time casting.
- Parquet supports
Float16, MAP columns without LogicalType, field and
file-level metadata, IEEE 754 total-ordering metadata, and sink field IDs.
- Arrow decimals remain Decimal, chunked Arrow structs consume every chunk,
Arrow map nulls survive import, and Enum exports are ordered dictionaries.
- PyArrow-backed
read_parquet and read_csv support index-based column
selection.
Spreadsheets, CSV, and databases
- Excel defaults to
calamine; choose engine="xlsx2csv" when engine options
are required.
- Spreadsheet readers accept raw bytes and named Excel tables; Excel output can
target file-like objects.
- Validate CSV schema overrides and configure multi-file inference with
infer_schema_files where needed.
- ADBC append creates a missing destination table.
- Database reads can infer
Int128.
SQL checkpoints
- Frame methods query only their own frame. Use top-level
pl.sql(...) for
queries involving multiple frames.
/ is true division. Use an explicit operation when integer quotient behavior
is required.
- Aggregate
FILTER, STRING_AGG, QUANTILE_DISC, and TOTAL are available.
SUM and CORR return null for all-null inputs.
LIKE and ILIKE can span newline characters.
- Invalid
sql_expr input and HAVING outside GROUP BY fail early.
Deprecation checklist
Plan replacements for these interfaces:
StringCache.
- dataframe interchange protocol integration.
- IPC scan cache arguments.
rolling_corr(ddof=...).
- implicit
show_graph() plan stage and implicit .explode() empty handling.
- integer/Boolean bitwise mixing, string-to-temporal casts, and non-nested-to-
List casts.
- numeric-to-Categorical and Categorical-to-integer casts, plus
cat.get_categories() and cat.to_local().
- mismatched name counts passed to
struct.rename_fields().
Use Expr.cat.to for explicit categorical conversion and Expr.cat.physical
for access to its physical representation. Follow PEP 702 diagnostics in static
analysis, since deprecated Polars APIs carry compatible annotations.
Validation workflow
Before accepting a migration:
- Pin and record the Polars version used by tests.
- Assert schemas, not only row values, around Arrow, Parquet, JSON, Enum,
Decimal, Array, and categorical boundaries.
- Test lazy and streaming plans against representative nulls, empty inputs,
duplicate names, and invalid casts.
- Re-run SQL assertions involving division, null aggregates, literals, joins,
multiline strings, and invalid syntax.
- Round-trip serialization and remote I/O with the same engines and credential
setup used in production.
- Consult the topic references for exact option names, defaults, and versioned
behavior before changing compatibility code.
1---2name: polars-knowledge-patch-23description: Polars4license: MIT5---678# Polars Knowledge Patch910Use this skill when writing, reviewing, debugging, or migrating Polars code in11Python, Rust, or SQL. Check the project's pinned Polars version first and apply12only guidance relevant to that version. Prefer the project's schema, code, and13tests when they establish behavior more directly.1415## Reference index1617| Reference | Topics |18| --- | --- |19| [`data-types-and-expressions.md`](references/data-types-and-expressions.md) | Construction, dtypes, nested data, expressions, aggregation, temporal behavior |20| [`io-and-serialization.md`](references/io-and-serialization.md) | Parquet, Arrow, CSV, Excel, databases, cloud storage, serialization |21| [`lazy-execution-and-joins.md`](references/lazy-execution-and-joins.md) | Lazy schemas, optimizations, streaming, joins, grouping, sinks |22| [`migration-and-deprecations.md`](references/migration-and-deprecations.md) | Breaking defaults, renamed APIs, deprecations, exceptions, runtime support |23| [`sql.md`](references/sql.md) | SQL operators, functions, aggregates, joins, validation, frame scope |2425## Migration triage2627When upgrading an existing application, check these high-impact changes first:28291. Make row orientation explicit when constructing heterogeneous frames:3031 ```python32 pl.DataFrame([[1, "a"], [2, "b"]], orient="row")33 ```34352. Expect inferred `Series` construction to be strict. Use `strict=False` only36 when common-dtype inference or casting is intentional.373. Replace dtype-changing `replace` calls with `replace_strict`; supply a38 `default` when unmapped values must survive.394. Read serialized frames with `deserialize`, not `read_json`. Default40 serialization is binary; request `format="json"` explicitly for JSON.415. Audit Parquet path behavior. Directories enable Hive partitioning by default,42 while files, globs, and file lists do not.436. Replace repeated lazy metadata access with one `collect_schema()` call.447. Review SQL integer division: `/` uses true division and may return fractions.458. Remove reliance on implicit optimization in `map_batches`; its default is no46 optimizer transformations.4748## Construction and schema4950### Build frames and series deliberately5152- A zoned datetime dtype converts input values into its zone. It does not merely53 replace time-zone metadata, so naive wall-clock values may shift.54- Two-dimensional NumPy input and `Series.reshape` produce fixed-size `Array`55 values. Convert with `.arr.to_list()` when callers require `List`.56- Byte scalars in a `DataFrame` constructor broadcast across rows.57- Empty JSON construction preserves its schema.58- Duplicate names in an Arrow table, and duplicate names in a Parquet file,59 raise `DuplicateError`.60- Use `LazyFrame.match_to_schema(...)` to reconcile a lazy input with an expected61 schema before execution.6263### Treat nested conversion as strict6465`strict=True` validates conversions inside nested values, not only the outer66dtype. Align Enum category sets before appending; appending no longer merges67different category definitions.6869For nested queries and transformations:7071- `list.contains` and `arr.contains` accept `nulls_equal`.72- List and Array `any`/`all` accept `ignore_nulls`.73- List and Array support `is_unique`.74- Fixed-size Array columns can be grouping keys.75- `list.slice` broadcasts scalar input across rows.7677## Expression behavior7879### Handle nulls explicitly8081- EWM mean, standard deviation, and variance preserve input null positions. Add82 `.forward_fill()` only when reproducing the earlier filled result.83- The initial unbiased `ewm_var` and `ewm_std` value is null.84- A null `clip` bound leaves the original value unchanged.85- `fill_null` operates on columns whose dtype is `Null`.86- Rolling-by expressions propagate nullness from their `by` column.8788### Update selection and replacement code8990- `pl.nth` positional arguments are indices. Use `pl.col("a").get(1)` to select91 an element from a named expression.92- `get` and `gather` raise for out-of-bounds indices unless93 `null_on_oob=True` is passed.94- `Series.equals` ignores names unless `check_names=True`.95- `replace_strict` supports Enum values and raises for unmapped non-null input96 when no default is supplied.9798### Check changed numerical results99100- Decimal sums widen result precision and raise instead of wrapping on overflow.101- Covariance with a constant returns zero rather than `NaN`.102- `rolling_corr` ignores its deprecated `ddof` argument.103- Globally seeded sampling is reproducible because `sample()` honors the global104 random seed.105- Datetime truncation is epoch-aligned; weekly buckets remain Monday-aligned.106107## Lazy execution and streaming108109### Collect schemas once110111Access to `LazyFrame.schema`, `.dtypes`, `.columns`, and `.width` can trigger an112expensive schema resolution and warns accordingly. Prefer:113114```python115schema = lf.collect_schema()116names = schema.names()117```118119Use `QueryOptFlags` when customizing lazy optimization. Persisted expressions or120plans must use a DSL representation compatible with the reader; incompatible121representations are rejected.122123### Use the streaming engine as supported execution124125The streaming engine is stable and supports a broad set of operations, including126additional group-by aggregations, grouped as-of joins, native interpolation,127format-inferred `strptime`, covariance/correlation, PyArrow dataset sources, and128Parquet sinks. Grouped as-of joins preserve null rows.129130Callback sinks can write cloud targets, and external `object_store`131implementations can add schemes beyond the native set. Configure132`POLARS_OOC_DISK_BUDGET_MB` to bound disk space for out-of-core spilling.133134## I/O checkpoints135136### Parquet and Arrow137138- Unprojected Parquet columns are not dtype-validated during projected reads.139- Use `scan_parquet(..., cast_options=...)` to control scan-time casting.140- Parquet supports `Float16`, MAP columns without `LogicalType`, field and141 file-level metadata, IEEE 754 total-ordering metadata, and sink field IDs.142- Arrow decimals remain Decimal, chunked Arrow structs consume every chunk,143 Arrow map nulls survive import, and Enum exports are ordered dictionaries.144- PyArrow-backed `read_parquet` and `read_csv` support index-based column145 selection.146147### Spreadsheets, CSV, and databases148149- Excel defaults to `calamine`; choose `engine="xlsx2csv"` when engine options150 are required.151- Spreadsheet readers accept raw bytes and named Excel tables; Excel output can152 target file-like objects.153- Validate CSV schema overrides and configure multi-file inference with154 `infer_schema_files` where needed.155- ADBC append creates a missing destination table.156- Database reads can infer `Int128`.157158## SQL checkpoints159160- Frame methods query only their own frame. Use top-level `pl.sql(...)` for161 queries involving multiple frames.162- `/` is true division. Use an explicit operation when integer quotient behavior163 is required.164- Aggregate `FILTER`, `STRING_AGG`, `QUANTILE_DISC`, and `TOTAL` are available.165- `SUM` and `CORR` return null for all-null inputs.166- `LIKE` and `ILIKE` can span newline characters.167- Invalid `sql_expr` input and `HAVING` outside `GROUP BY` fail early.168169## Deprecation checklist170171Plan replacements for these interfaces:172173- `StringCache`.174- dataframe interchange protocol integration.175- IPC scan cache arguments.176- `rolling_corr(ddof=...)`.177- implicit `show_graph()` plan stage and implicit `.explode()` empty handling.178- integer/Boolean bitwise mixing, string-to-temporal casts, and non-nested-to-179 `List` casts.180- numeric-to-Categorical and Categorical-to-integer casts, plus181 `cat.get_categories()` and `cat.to_local()`.182- mismatched name counts passed to `struct.rename_fields()`.183184Use `Expr.cat.to` for explicit categorical conversion and `Expr.cat.physical`185for access to its physical representation. Follow PEP 702 diagnostics in static186analysis, since deprecated Polars APIs carry compatible annotations.187188## Validation workflow189190Before accepting a migration:1911921. Pin and record the Polars version used by tests.1932. Assert schemas, not only row values, around Arrow, Parquet, JSON, Enum,194 Decimal, Array, and categorical boundaries.1953. Test lazy and streaming plans against representative nulls, empty inputs,196 duplicate names, and invalid casts.1974. Re-run SQL assertions involving division, null aggregates, literals, joins,198 multiline strings, and invalid syntax.1995. Round-trip serialization and remote I/O with the same engines and credential200 setup used in production.2016. Consult the topic references for exact option names, defaults, and versioned202 behavior before changing compatibility code.