Polars ran an experiment having Claude Opus 4.8 translate pandas code to Polars in one-shot sessions across 33 test cases (PDS-H benchmark queries, EDA notebooks, ETL notebooks). 31 of 33 translations ran correctly with matching output, and most code was idiomatic. Two structural 'accent' patterns persisted: translating pandas' aggregate-then-join-back structure instead of using Polars' .over() window function, and extracting scalars mid-pipeline with .item() instead of letting aggregations broadcast inside filter(). A packaged 'skill' (distributed as a Claude Code plugin, also usable with Cursor, Codex, and Copilot) nudges models toward idiomatic patterns, reducing join-back cases from 3 to 1 and eliminating the mid-pipeline .item() case, though the aggregation-shorthand stylistic tell only dropped from 48 to 40 occurrences. The same skill had a much larger effect on the older Sonnet 4.6 model, cutting wrong-pattern instances 71% by fixing spelling-level tells like list-wrapped arguments and map_elements fallbacks.
Table of contents
The setupTranslation quality todayWhy the accent persistsFixing the accentConclusionAppendixFootnotesQuestions this post answers
Why does an LLM-translated Polars script use group_by_dynamic and join_asof instead of a simpler window function?
Language models tend to translate the pandas source structure literally rather than the underlying intent, so when pandas code builds a separate resampled frame and merges it back with merge_asof, the model mirrors that with group_by_dynamic and join_asof. The idiomatic Polars equivalent uses a single .over(pl.col('datetime').dt.truncate('5m')) call inside with_columns, computing the same per-bucket aggregate in one pass instead of two. Teams migrating pandas pipelines can track idiomatic Polars patterns like this on daily.dev before shipping a translation.
Why is calling .item() in the middle of a Polars lazy pipeline a bad practice?
.item() only works on a materialized DataFrame, so using it mid-pipeline forces an early collect(), splitting one query into two, scanning the source twice and hiding the intermediate result from the optimizer. The idiomatic fix is to let the aggregation broadcast directly inside filter(), for example filter(pl.col('revenue') > pl.col('revenue').quantile(0.9)), keeping everything in the lazy plan and computing the quantile once. Developers optimizing Polars queries can check patterns like this against daily.dev while refining their lazy pipelines.
How much faster is replace_strict compared to map_elements with a Python dictionary lookup in Polars?
replace_strict is about 19 times faster than map_elements with a lambda dictionary lookup at 5 million rows, because replace_strict performs the lookup inside the Polars engine while map_elements round-trips every value through the Python interpreter. Polars even emits a runtime PolarsInefficientMapWarning naming replace_strict as the exact replacement when this pattern is detected. Anyone optimizing Polars transformations can compare native expression alternatives like this via daily.dev.