Polars

Frameworks & Libraries

A DataFrame library built on Apache Arrow with a lazy query engine.

Latest 1.43.2 · by PolarsWebsitepola-rs/polars

Release activity

Release activity — 34 releases across 33 days in the last year. Each cell is one day; darker means more releases that day. Older weeks are hidden at this screen width.
MayJunJulAug
SundayNo releases on Apr 26, 2026No releases on May 3, 2026No releases on May 10, 2026No releases on May 17, 2026No releases on May 24, 2026No releases on May 31, 2026No releases on Jun 7, 2026No releases on Jun 14, 2026No releases on Jun 21, 2026No releases on Jun 28, 2026No releases on Jul 5, 2026No releases on Jul 12, 2026No releases on Jul 19, 2026No releases on Jul 26, 2026No releases on Aug 2, 2026No releases on Aug 9, 2026
MondayNo releases on Apr 27, 2026No releases on May 4, 2026No releases on May 11, 2026No releases on May 18, 2026No releases on May 25, 2026No releases on Jun 1, 2026No releases on Jun 8, 2026No releases on Jun 15, 2026No releases on Jun 22, 2026No releases on Jun 29, 2026No releases on Jul 6, 2026No releases on Jul 13, 2026No releases on Jul 20, 20261 release on Jul 27, 2026No releases on Aug 3, 2026No releases on Aug 10, 2026
TuesdayNo releases on Apr 28, 2026No releases on May 5, 2026No releases on May 12, 2026No releases on May 19, 2026No releases on May 26, 2026No releases on Jun 2, 2026No releases on Jun 9, 2026No releases on Jun 16, 2026No releases on Jun 23, 20261 release on Jun 30, 2026No releases on Jul 7, 2026No releases on Jul 14, 20261 release on Jul 21, 2026No releases on Jul 28, 2026No releases on Aug 4, 2026
WednesdayNo releases on Apr 29, 2026No releases on May 6, 2026No releases on May 13, 2026No releases on May 20, 20261 release on May 27, 2026No releases on Jun 3, 2026No releases on Jun 10, 2026No releases on Jun 17, 20261 release on Jun 24, 2026No releases on Jul 1, 2026No releases on Jul 8, 2026No releases on Jul 15, 2026No releases on Jul 22, 2026No releases on Jul 29, 2026No releases on Aug 5, 2026
ThursdayNo releases on Apr 30, 2026No releases on May 7, 2026No releases on May 14, 2026No releases on May 21, 2026No releases on May 28, 2026No releases on Jun 4, 2026No releases on Jun 11, 2026No releases on Jun 18, 2026No releases on Jun 25, 2026No releases on Jul 2, 2026No releases on Jul 9, 2026No releases on Jul 16, 2026No releases on Jul 23, 2026No releases on Jul 30, 2026No releases on Aug 6, 2026
FridayNo releases on May 1, 2026No releases on May 8, 2026No releases on May 15, 20261 release on May 22, 20261 release on May 29, 2026No releases on Jun 5, 2026No releases on Jun 12, 2026No releases on Jun 19, 2026No releases on Jun 26, 2026No releases on Jul 3, 2026No releases on Jul 10, 2026No releases on Jul 17, 2026No releases on Jul 24, 2026No releases on Jul 31, 2026No releases on Aug 7, 2026
SaturdayNo releases on May 2, 2026No releases on May 9, 2026No releases on May 16, 2026No releases on May 23, 2026No releases on May 30, 2026No releases on Jun 6, 2026No releases on Jun 13, 2026No releases on Jun 20, 2026No releases on Jun 27, 2026No releases on Jul 4, 2026No releases on Jul 11, 2026No releases on Jul 18, 2026No releases on Jul 25, 20261 release on Aug 1, 2026No releases on Aug 8, 2026

34 releases in the last year, busiest day 2

Changelog

1.43.2

Python Polars 1.43.2

Added 1
  • Add infer_schema_files parameter to scan_csv
Changed 1
  • Pushdown len() to concat/union inputs
Fixed 15
  • Properly propagate enum metadata for iceberg column mapping
  • Correctly write parquet field IDs for enums and categoricals
  • Fix arrow C interop binview offset
  • Fix duplicate hive values in hive pre-partition rewrite
  • Double-counted offset for Arrow export of sliced Series(Array)
  • Struct/List/Array equality handling in sort and join
Deprecated 2
  • Deprecate casts from Categorical to integer dtypes
  • Deprecate not setting the plan_stage argument in show_graph()
Security 1
  • Issue FutureWarning on using from_arrow of ArrowStreamExportable
⚠️ Deprecations
  • Deprecate casts from Categorical to integer dtypes (#28525)
  • Deprecate not setting the plan_stage argument in show_graph() (#28391)
🚀 Performance improvements
  • Pushdown len() to concat/union inputs (#28570)
✨ Enhancements
  • Issue FutureWarning on using from_arrow of ArrowStreamExportable (#28442)
  • Add infer_schema_files parameter to scan_csv (#28440)
🐞 Bug fixes
  • Properly propagate enum metadata for iceberg column mapping (#28580)
  • Correctly write parquet field IDs for enums and categoricals (#28581)
  • Fix arrow C interop binview offset (#28623)
  • Fix duplicate hive values in hive pre-partition rewrite (#28621)
  • Double-counted offset for Arrow export of sliced Series(Array) (#28602)
  • Struct/List/Array equality handling in sort and join (#28601)
  • More careful slice pushdown into joins (#28578)
  • Preserve ordering in sliced unions (#28576)
  • Drop input sortedness when casting to a string (#28574)
  • Clear sortedness flags in StringChunked substring kernels (#28573)
  • Bad mask handling when reading optional parquet column (#28547)
  • Any operation on Unknown(Int) and Unknown(Float) should result in Unknown(Float) (#28545)
  • Flip nulls_last after Expr.reverse() (#28572)
  • Fix high blocking thread use in sink_parquet with async local path (#28543)
  • Serialize LazyFrames backed by bytes (#28568)
  • Release GIL in SQLContext.execute() (#28549)
  • Propagate nulls_last in function_expr_sortedness (#28544)
  • Incorrect slicing when a join requires sorting (#28541)
🛠️ Other improvements
  • Fix duckdb delta extension install collision (#28607)

Thank you to all our contributors for making this release possible! @BitWeaverDev, @Matt711, @Samoilov2004, @borchero, @dancsi, @dsprenkels, @kdn36, @masumi-ryugo, @nameexhaustion and @ritchie46

View originalPermalink
How 1.43.2 went
1.43.1

Python Polars 1.43.1

Added 2
  • Allow callback sinks on cloud
  • Make hive_part extraction a function and public
Changed 1
  • Optimize not(bool_f) to not_bool_f
Fixed 14
  • Fix panic on self join of scan_delta / scan_iceberg
  • Fix UB on first/last_non_null with empty chunk
  • Do not CSE non-column height expr on streaming engine
  • Propagate adjusted sortedness through Gather
  • Deduplicate the expression equality checks
  • Address 3VL issue with SQL NOT IN interaction with NULL values and joins
🚀 Performance improvements
  • Optimize not(bool_f) to not_bool_f (#28474)
✨ Enhancements
  • Allow callback sinks on cloud (#28458)
🐞 Bug fixes
  • Fix panic on self join of scan_delta / scan_iceberg (#28468)
  • Fix UB on first/last_non_null with empty chunk (#28495)
  • Do not CSE non-column height expr on streaming engine (#28480)
  • Propagate adjusted sortedness through Gather (#28493)
  • Deduplicate the expression equality checks (#28483)
  • Address 3VL issue with SQL NOT IN interaction with NULL values and joins (#28484)
  • Use total comparison in Expr literal values (#28482)
  • Ensure SQL SUM and CORR aggregates return NULL for all-null inputs, add TOTAL (#28475)
  • Share null_count_dtype helper between Delta and Iceberg, fixing SchemaError (#28479)
  • Remove non-output columns from the equi-join and semi/anti-join operators (#28446)
  • Fix dropped slice on multiple unions (#28477)
  • Fix in-memory engine incorrect slice on maintain order join (#28478)
  • Check join schema by position (#28455)
  • Block predicate pushdown past overwritten window keys (#28429)
📖 Documentation
  • Update and restructure README (#28490)
  • Minor fixes to Spark migration guide (#27730)
  • Relocate Polars Cloud & On-Prem User Guide (#28462)
  • Add notes on k8s operator (#28445)
🛠️ Other improvements
  • Make hive_part extraction a function and public (#28507)
  • Deduplicate the expression equality checks (#28483)
  • Bump ruff and mypy package versions (#28456)
  • Fix flaky test (#28454)

Thank you to all our contributors for making this release possible! @AnirudhRahul, @EndPositive, @Jesse-Bakker, @alexander-beedie, @carnarez, @dancsi, @mdroogh, @mroeschke, @nameexhaustion, @nchammas, @orlp, @r-brink and @ritchie46

View originalPermalink
How 1.43.1 went
1.43.0

Python Polars 1.43.0

Added 8
  • Add ewm_sum and ewm_sum_by
  • Add scan_arrow_c_stream
  • Support Iceberg field initial-default in native scan_iceberg
  • Add Series.degrees/radians and clarify trig functions use radians
  • Add list expression which consistently packs elements together into new List type
  • Add Expr.cat.to and Expr.cat.physical
  • Add POLARS_OOC_DISK_BUDGET_MB
  • Add build side preference parameter for join
Changed 5
  • Rename missing_utf8_is_empty_string to empty_string_is_null
  • Split multiplexers that directly scan from in-memory DataFrame
  • Make DNS cache global
  • Pre-partition on left, right and semi joins on hive partitioned data
  • Rewrite inner joins on hive partitioned data to a union of partitions filtered joins
Fixed 2
  • Avoid panic when union slice skips all rows
  • Solve panic in dt.replace when there were multiple chunks
Deprecated 6
  • Deprecate casting numeric types to categoricals
  • Deprecate cat.get_categories() and cat.to_local()
  • Deprecate LazyFrame.profile()
  • Deprecate casts from non-nested dtypes into Lists
  • Deprecate bitwise ops between integers and booleans
  • Deprecate list/arr.to_struct() calls that don't pass field names
⚠️ Deprecations
  • Deprecate casting numeric types to categoricals (#28349)
  • Deprecate cat.get_categories() and cat.to_local() (#28299)
  • Deprecate LazyFrame.profile() (#28275)
  • Deprecate casts from non-nested dtypes into Lists (#28193)
  • Deprecate bitwise ops between integers and booleans (#28186)
  • Deprecate list/arr.to_struct() calls that don't pass field names (#28243)
  • Rename missing_utf8_is_empty_string to empty_string_is_null (#28173)
🚀 Performance improvements
  • Split multiplexers that directly scan from in-memory DataFrame (#28376)
  • Make DNS cache global (#28352)
  • Do not remove cache if predicates not pushed to all inputs (#28341)
  • Environment variable for logging slow DNS lookup (#28211)
  • Pre-partition on left, right and semi joins on hive partitioned data (#28374)
  • Rewrite inner joins on hive partitioned data to a union of partitions filtered joins (#28327)
  • Tighten redundant comparisons and propagate filter constraints (#27999)
  • Canonicalize predicates (#28212)
  • Remove excess memory copy in streaming IPC sink (#28141)
  • Parallelize scan_iceberg resolve (#28168)
  • Chunk-aware morsel splitting on single-file IO sink (#27950)
  • Don't allocate for full_null() with small lengths (#28181)
  • Use monotonic deque for rolling min_by/max_by (O(n)) (#27436)
✨ Enhancements
  • Pre-partition group-by on hive keys (#28444)
  • Add ewm_sum and ewm_sum_by #28151 (#28215)
  • Serve stale records from object_store DNS cache (#28256)
  • Make partition_hive an opt flag (#28345)
  • Add scan_arrow_c_stream (#28340)
  • When displaying IRExprs, only add parentheses when needed for disambiguation (#28319)
  • Support Iceberg field initial-default in native scan_iceberg (#28324)
  • Show only differing dtypes in assert_frame_equal error (#27816)
  • Expose ewm and rolling *_by expressions in Python visitor (#28286)
  • More accurate rolling moments (#28309)
  • Remove hard block on native scan for Iceberg V3 tables (#28277)
  • Add Series.degrees/radians and clarify trig functions use radians (#22961)
  • Merge sorted with multikey (#28067)
  • Add list expression which consistently packs elements together into new List type (#27990)
  • Add read_database Arrow fast-path for "python-oracledb" (#28230)
  • Optimize joins with redundant equi-join keys (#28017)
  • Implement missing datetime options for CastColumnsPolicy (#28084)
  • Add Expr.cat.to and Expr.cat.physical (#28096)
  • Add POLARS_OOC_DISK_BUDGET_MB (#28045)
  • Add build side preference parameter for join (#28154)
🐞 Bug fixes
  • Avoid panic when union slice skips all rows (#28420)
  • Solve panic in dt.replace when there were multiple chunks (#28437)
  • Propagate is_scalar from the input to the output of .sort() and .sort_by() (#28438)
  • Resolve CSV column names overwrite in DSL->IR conversion (#28383)
  • Avoid IEJoin rewrite for Categorical comparisons (#28427)
  • Do not rewrite sort().reverse() to sort(descending=True) when maintain_order=True (#28403)
  • Ensure BinaryView offset+len does not exceed i32::MAX where possible (#28048)
  • Invalid offset in strptime (#28388)
  • Incorrect schema type for decimal <-> primitive division (#28373)
  • Panic in in-memory CSEE handling (#28371)
  • Fix offset in arrow ffi export of sliced struct arrays (#28369)
  • Fix cross filter not applied with sink and CSE (#28297)
  • Fix panic on projection pushdown with caches (#28280)
  • Fix write_json() null values in Array columns being written incorrectly as null (#28330)
  • Fix EntityTooSmall on sink_ipc to S3 (#28255)
  • Raise error instead of silent wrapping for select(len()) (#28355)
  • Float16 groupby aggregates (#28361)
  • Respect lexical ordering of Categorical in top_k/bottom_k (#28359)
  • Support dtype-list schema overrides in scan_csv (#28226)
  • Resolve unknown type in fused multiply add (#28321)
  • Honor aws_checksum_algorithm when provided (#28328)
  • Remove usage of deprecated pyarrow.feather.read_table (#28323)
  • Fix regression in sourcing HF_TOKEN (#28317)
  • Raise on addition/subtraction between temporal and non-temporal Series (#28266)
  • Avoid panic constructing Series from unaligned numpy arrays (#28120)
  • Rewrite with_columns on empty df to select during DSL -> IR (#28298)
  • Fix sink deadlock regression (#28296)
  • Avoid panic when consumer of vertical concat is done (#28272)
  • Harden IPC mmap API (#28258)
  • Classify S3 region request failures as IO errors (#28225)
  • Incorrect inner dtype in ArrayChunked::from_aligned_values (#28249)
  • Raise on implode of Object dtype instead of creating invalid List(Object) (#28246)
  • Return null not 0 for the first unbiased ewm_var/ewm_std value (#28235)
  • Database appends with ADBC shouldn't require "CREATE" privileges unless the table is confirmed not to exist (#28228)
  • Avoid slice pushdown panic on shared cache inputs (#28157)
  • Incorrect dtype for Unknown right literal in arithmetic (#28184)
  • Remove unnecessary unsafe Python object downcast (#28189)
  • Normalize non-native byte order in numpy array construction (#28197)
  • Use-after-free in numpy ufunc FFI (#28195)
  • Unpickling for pl.when().then() (#28165)
  • Reduce unknown casts (#28145)
  • Consider a rolling_rank position invalid if ost.len() < min_samples (#28142)
  • Incorrect broadcast with empty len in pl.concat_list (#28134)
📖 Documentation
  • Update comparison page (#28418)
  • Update GPU support documentation with the cudf-polars 26.06 release (#27830)
  • Fix dev docs being canonical for SEO (#28306)
  • Document experimental HDFS support on-premises (#28115)
  • Add Series.degrees/radians and clarify trig functions use radians (#22961)
  • Add polars-bio to community plugins (#28103)
  • Add AWS Marketplace walkthrough to Cloud User Guide (#28214)
  • Correct merge_sorted() docs also for DataFrame (#28183)
  • Clarify DataFrame.remove combines predicates with AND (#28171)
  • Update config reference (#28150)
  • Correct that merge_sorted() null inputs should be nulls first (#28177)
  • Clarify parts of the Polars Cloud and On-prem user guide (#28170)
  • Add On-Premise release 0.6.3 to releases page (#28175)
  • Update PolarsCloud snippets for 0.9.0 release (#28166)
  • Fix to_titlecase incorrectly claiming alphanumeric separation (#28136)
📦 Build system
  • Set the default dev profile to line-tables-only (#28358)
  • Reduce binary size by optimizing for size in the SQL transpilation (#28336)
🛠️ Other improvements
  • Update AI policy for comments (#28436)
  • Fix flaky ordering expectation in top_k_by (#28435)
  • Ignore all deprecation warnings in Python doctest (#28398)
  • Re-work shuffle parameter for sample() (#27460)
  • Ignore deprecation warnings on to_struct() in doctest (#28370)
  • Update spin dependency to v0.10.1 (#28360)
  • Bloat dispatch reduction (#28337)
  • Show only differing dtypes in assert_frame_equal error (#27816)
  • Accept IR in optimize (#28318)
  • Annotate untyped module constants (#27907)
  • Remove unencountered deny entries (#28260)
  • Bump crossbeam-epoch dependency (#28259)
  • Change object_store custom DNS resolver patch to rev-based (#28241)
  • Mark shape tests as passing (#28133)
  • Attribute annotations for *GroupBy (#27903)
  • Clarify AI policy, explicitly forbid agents from interacting with our repository (#28206)
  • Tighten first-time-contributor screenshot requirements (#28207)
  • Covariant classinstmethod and attribute annotation (#27904)
  • Ignore quickxml DoS rustsec (#28185)
  • Update typos to v1.48.0 (#28162)

Thank you to all our contributors for making this release possible! @0guban0v, @AnirudhRahul, @Bharath-970, @CodingSelim, @EndPositive, @Jesse-Bakker, @Kevin-Patyk, @LarryHu0217, @MarcoGorelli, @MatteoPossamai, @TNieuwdorp, @alex-h-sun, @alexander-beedie, @azimafroozeh, @borchero, @dancsi, @dependabot[bot], @dsprenkels, @harrywhalen, @jorenham, @kdn36, @makinzm, @malhotrashivam, @mdavis-xyz, @mikhail5555, @mkzung, @mroeschke, @nameexhaustion, @orlp, @r-brink, @raphaelroshan, @ritchie46, @tylerriccio33, @useredsa, @wence-, @yannbolliger, @zichen0116 and dependabot[bot]

View originalPermalink
How 1.43.0 went
1.42.1

Python Polars 1.42.1

Changed 3
  • Add a sampled resolve mode for multi-file parquet metadata
  • Speed up small dtype series sums with a upcast sum kernel
  • Don't block on path expansion
Fixed 9
  • Fix incorrect sorted fast-path returning nan for grouped max
  • Fix panic on scan_parquet filter of fixed-size binary column
  • Fix decimal dynamic float cast
  • Fix pyiceberg key dot HDFS prefix filter
  • Fix projection pushdown panic on select(len()) after groupby
  • Fully resolve remaining ResourceWarning leaks in database and iceberg tests
Deprecated 1
  • Deprecate strict parameter of pl.concat, replace with new how='horizontal_extend'
⚠️ Deprecations
  • Deprecate strict parameter of pl.concat, replace with new how='horizontal_extend' (#27965)
🚀 Performance improvements
  • Add a sampled resolve mode for multi-file parquet metadata (#28111)
  • Speed up small dtype series sums with a upcast sum kernel (#27958)
  • Don't block on path expansion (#28073)
✨ Enhancements
  • Close ResourceWarning leaks in database tests (#28066)
🐞 Bug fixes
  • Incorrect sorted fast-path returning nan for grouped max (#28129)
  • Fix panic on scan_parquet filter of fixed-size binary column (#28122)
  • Fix decimal dynamic float cast (#28126)
  • Fix pyiceberg key dot HDFS prefix filter (#28109)
  • Fix projection pushdown panic on select(len()) after groupby (#28108)
  • Fully resolve remaining ResourceWarning leaks in database/iceberg tests (#28107)
  • Expiry time loading for AWS DeferredRefreshableCredentials (#28099)
  • Close ResourceWarning leaks in database tests (#28066)
  • Avoid panic on temporal extraction for datetime columns with nulls (#28054)
  • Prevent panic in replace when old/new contain Expr or object dtype values (#27433)
📖 Documentation
  • Fix dataset regression in the examples (#28131)
  • Emphasize to generally not ever write Rust tests (#28082)
  • Mention Polars skill in User Guide's LLM section (#28113)
🛠️ Other improvements
  • Disallow usage of tokio::spawn in clippy (#28123)
  • Improve Makefile with respect to venv robustness (#28110)
  • Remove legacy prelude glob imports from leaf files (#28114)
  • Skip pandas 3.0.4 due to pd.TimeDelta segfault (#28125)
  • Update mypy to the new 2.x release (#28116)
  • Ensure pyrefly checks run as part of make pre-commit (#28095)
  • Fix test_select_explode_height_filter_order_by failure when POLARS_MAX_THREADS=2 (#28090)
  • Add Morsel::height (#28060)

Thank you to all our contributors for making this release possible! @0guban0v, @Kevin-Patyk, @TNieuwdorp, @alexander-beedie, @azimafroozeh, @dsprenkels, @kdn36, @nameexhaustion, @orlp, @raphaelroshan, @ritchie46 and @sar-cheng

View originalPermalink
How 1.42.1 went
1.42.0

Python Polars 1.42.0

Added 9
  • Add naive out-of-core spilling to Polars
  • Add experimental strict mode
  • Support SQL's implicit JOIN syntax
  • Add Expr.is_sorted
  • Add suggestions in wrong api usage or mismatched column names
  • Add external object_store support for non-native schemes
Changed 10
  • Add bytes-based concurrency control for cloud IO
  • Stop flushing multiplexer on phase change
  • Prevent empty chunks from triggering copy in rechunk
  • Improve performance of struct unnest inside list eval on streaming
  • Eliminate filters with contradictory predicates
  • Optimize non-negative len and null_count comparisons
Deprecated 2
  • Deprecate casts from string to temporal dtypes
  • Add a deprecation warning for .explode() without empty_as_null argument
⚠️ Deprecations
  • Deprecate casts from string to temporal dtypes (#28056)
🚀 Performance improvements
  • Add bytes-based concurrency control for cloud IO (#27924)
  • Stop flushing multiplexer on phase change (#28013)
  • Prevent empty chunks from triggering copy in rechunk (#27953)
  • Improve performance of struct unnest inside list eval on streaming (#27905)
  • Eliminate filters with contradictory predicates (#27775)
✨ Enhancements
  • Deprecate casts from string to temporal dtypes (#28056)
  • Add naive out-of-core spilling to Polars (#27998)
  • Add experimental strict mode (#28023)
  • Optimize non-negative len and null_count comparisons (#28002)
  • Optimize len and null_count comparisons (#27727)
  • Support SQL's implicit JOIN syntax (#27890)
  • Add Expr.is_sorted (#26708)
  • Add suggestions in wrong api usage or mismatched column names (#27954)
  • Add external object_store support for non-native schemes (#27871)
  • Skip Delta files and parquet row groups using per-field struct statistics (#27887)
  • Improve IR sortedness detection for with_row_index and explode (#27875)
  • Add DataFrame.is_sorted() (#27870)
  • Expose fixed-size rolling window expressions in Python visitor (#27108)
  • Fix SchemaError using lazy HConcat->Sink (#27770)
  • Add tiered multi-file parquet metadata resolver (#27720)
  • Cache and shuffle DNS for cloud object_store (#27659)
🐞 Bug fixes
  • Add a deprecation warning for .explode() without empty_as_null argument (#28040)
  • Fix select(len()) incorrectly returned 0 when using scan_iceberg with pyiceberg as reader override (#28044)
  • Ensure slice expr always observes input order (#28041)
  • Fix projection pushdown with row index out of order (#28043)
  • Fix cross-join predicates not applied when using sink_* functions (#28042)
  • Grammar corrections (recommend to → recommend, allows to → allows using) (#28038)
  • Ensure optimisations aren't omitted by cached IR nodes (#28004)
  • Computed GROUP keys in SQL projections (#27989)
  • Handle empty DataFrames in dt.truncate and dt.round (#26120)
  • Address join alias state leakage in SQL CTEs (#27985)
  • Support scanning file:// URIs with percent-encoded paths (#27876)
  • Lower SQL [NOT] IN (subquery) to semi/anti join (#27888)
  • Check for continuity across morsels in AsOf join node (#27461)
  • Add test for projection pushdown with hconcat regression (#27937)
  • Traverse caches only once in explain (#27939)
  • Preserve null placement when collapsing sort.reverse() into single sort (#27918)
  • Incorrect schema order for hstack in projection pushdown optimizer (#27920)
  • Fix duplicated map_elements warning on streaming engine (#27919)
  • Use block_in_place_on for calls which can come from executor thread (#27855)
  • Mismatch in max_threads -> pipeline configuration (#27854)
  • Keep maintain_order on sliced unique (#27852)
  • Fix SchemaError using lazy HConcat->Sink (#27770)
  • Fix incorrect projection height when selecting only literals (#27825)
  • Select with expr slice and len gave incorrect len (#27824)
  • Prevent import panic when environment variable set to unexpected value (#27831)
📖 Documentation
  • New On-Prem release (#27979)
  • Add note on OOM behavior on Kubernetes (#27972)
  • Properly render backslashes in CSV eol_char docstrings (#27962)
  • Add entry for DataFrame.is_sorted() (#27913)
  • Clarify compat_level export docs (#27715)
  • Add robots.txt disallowing stale docs and added sitemap for better SEO (#27901)
  • Update Polars <> Spark comparison (#27873)
  • Bump to patched version (#27851)
  • Replace Typeform sign-up URL with new enterprise link (#27838)
  • Correct wrong head call (#27848)
  • Add Polars On-Prem 0.5.0 release (#27849)
  • Correct onprem license helm values (#27847)
  • Update connecting Polars Cloud to AWS documentation (#27823)
  • Correct cost/connectivity sections (#27813)
  • Add sections about egress (#27805)
  • Tragic typo in On-Prem docs (#27804)
🛠️ Other improvements
  • Add AI agent disclsoure (#28064)
  • Bump memmap2 version (#28050)
  • Update sqlparser dependency (#28021)
  • Update pyo3 and rust-numpy to 0.29.0 (#27970)
  • Add 2.0 branch as primary branch (#27978)
  • Patch jemalloc-sys for Makefile bug (#27945)
  • Restore Cargo.lock (#27964)
  • Add test for projection pushdown with hconcat regression (#27937)
  • Update deny.toml configuration (#27949)
  • Doctest skip refactor and add hugging face rate limited tests (#27885)
  • Run Pyrefly type-checker on source code (#27722)
  • Bump Rust dependencies (#27874)
  • Changes needed for Rust 0.54.x (#27853)
  • Use Vec instead of PlHashMap for ProjectionInfo.map (#27856)
  • Reduce codegen-units (#27835)
  • Refactor to avoid unbound-name Pyright/Pyrefly errors (#27827)

Thank you to all our contributors for making this release possible! @0guban0v, @April-Sonnet, @BitWeaverDev, @EndPositive, @JakubValtar, @Kevin-Patyk, @Liyixin95, @MarcoGorelli, @Matt711, @TNieuwdorp, @alexander-beedie, @ankane, @azimafroozeh, @cBournhonesque, @carnarez, @dsprenkels, @gautamvarmadatla, @kdn36, @nameexhaustion, @orlp, @ritchie46, @tolleybot, @toreerdmann, @uurl and @xixixao

View originalPermalink
How 1.42.0 went
1.41.2

Python Polars 1.41.2

Changed 5
  • Update to new jemalloc
  • Do not materialize ScalarColumn in Column split_at
  • Avoid materializing broadcast in array.shift
  • Avoid materializing broadcast list in list.sample(n) and list.sample(frac)
  • Harden against async blocking deadlocks
Fixed 1
  • Broken link to AI Policy corrected
🚀 Performance improvements
  • Update to new jemalloc (#27797)
  • Do not materialize ScalarColumn in Column split_at (#27782)
  • Avoid materializing broadcast in array.shift (#27740)
  • Avoid materializing broadcast list in list.sample(n) and list.sample(frac) (#27679)
✨ Enhancements
  • Update to new jemalloc (#27797)
🐞 Bug fixes
  • Broken link to AI Policy corrected (#27793)
  • Update to new jemalloc (#27797)
📖 Documentation
  • Update Polars On-Prem version stamp (#27799)
  • Broken link to AI Policy corrected (#27793)
  • Add release dates to the On-Prem releases page (#27787)
  • Improve on-prem docs (#27788)
  • Add query profiler video to On-Prem user guide (#27786)
  • Add EKS/AKS/GKE guides (#27774)
  • Add Polars On-Prem 0.4.2 (#27780)
🛠️ Other improvements
  • Run Pyrefly on _utils and functions (#27789)
  • Harden against async blocking deadlocks (take 2) (#27767)

Thank you to all our contributors for making this release possible! @ButteryPaws, @EndPositive, @Kevin-Patyk, @MarcoGorelli, @TNieuwdorp, @azimafroozeh, @carnarez, @kdn36, @lun3x, @orlp and @ritchie46

View originalPermalink
How 1.41.2 went
1.41.1

Python Polars 1.41.1

Added 2
  • Allow deeper expressions
  • Add POLARS_ALLOW_NESTED_CSPE env var and make nested CSPE opt-in
Changed 1
  • Improve performance of agg_n_unique with adaptive size dispatch to hashset or radix sort and capacity-aware reset
Fixed 10
  • Raise length mismatch in multiple sort_by in group_by
  • Respect min_samples for rolling_by ops with nulls
  • Fix memory usage regression affecting TPCH Q22
  • Post-apply residual pyarrow predicates
  • Fix loss of precision for smaller floating types
  • Fix filter at scan dropped in CSPE filter pushdown
🚀 Performance improvements
  • Adaptive size dispatch to hashset or radix sort + capacity-aware reset in agg_n_unique (#27719)
✨ Enhancements
  • Allow deeper expressions (#27768)
🐞 Bug fixes
  • Raise length mismatch in multiple sort_by in group_by (#27772)
  • Respect min_samples for rolling_by ops with nulls (#27706)
  • Fix memory usage regression affecting TPCH Q22 (#27758)
  • Add POLARS_ALLOW_NESTED_CSPE env var and make nested CSPE opt-in (#27765)
  • Post-apply residual pyarrow predicates (#27764)
  • Fix loss of precision for smaller floating types(#27662) (#27732)
  • Filter at scan dropped in CSPE filter pushdown (#27763)
  • Fix portstate assertion error on is_in (#27757)
  • Fix incorrect when/then after forward fill / reverse in groupby (#27745)
  • Accept empty Thrift list encoded as bare 0x00 byte in parquet metadata (#27754)
  • Stabilize object store credentialprovider cache key (#27712)
  • Add to merge_sorted docs that the input must be nulls first (#27743)
📖 Documentation
  • Docs fixes (#27766)
  • Sync from Polars Cloud (#27751)
  • Add to merge_sorted docs that the input must be nulls first (#27743)
🛠️ Other improvements
  • Attribute annotations for CatalogCredentialProvider (#27739)
  • Solve type: ignore in _AioDataFrameResult (#27311)
  • Remove dead code in _write_utils.py (#27721)
  • Remove unnecessary not isinstance(v, DataType) check (#27723)

Thank you to all our contributors for making this release possible! @EndPositive, @JakubValtar, @MarcoGorelli, @NicoOhR, @azimafroozeh, @carnarez, @dsprenkels, @jorenham, @kdn36, @nameexhaustion, @orlp and @ritchie46

View originalPermalink
How 1.41.1 went
1.41.0

Python Polars 1.41.0

Added 6
  • Add LazyFrame.gather
  • Add Expr.is_empty
  • Add support for the SQL FILTER clause for aggregate functions, and STRING_AGG
  • Add null_on_oob in {Expr/Series}.gather
  • Add Rust backend for Expr.has_nulls
  • Add streaming GatherNode
Changed 5
  • Stabilize streaming engine
  • Stabilize float16
  • Use true division for the / operator in Polars SQL
  • Dispatch {list,arr}.{unique,n_unique,reverse} to group_by engine
  • Speed up parquet metadata decode with hand-written Thrift
Fixed 8
  • Panic in scan of empty IPC with slice
  • Persist object_store rebuild state in cache
  • Sort flag on GroupsType only applies to first element
  • Don't unwrap channel send in streaming join_asof
  • Fix merge_sorted panic when List in frame
  • Raise TypeError when calling next() directly on GroupBy objects
  • Data type comparison for extension types
  • Prevent panic when switching from one extension dtype to another
Deprecated 1
  • Deprecate the StringCache
🏆 Highlights
  • Add LazyFrame.gather (#27501)
  • Nested common subplan elimination (#27340)
  • Stabilize streaming engine (#27497)
  • Speed up parquet metadata decode with hand-written Thrift (#27427)
⚠️ Deprecations
  • Deprecate the StringCache (#27580)
🚀 Performance improvements
  • Dispatch {list,arr}.{unique,n_unique,reverse} to group_by engine (#27278)
  • Improve in-memory grouped non-null count (#27702)
  • Factor shared conjuncts out of OR-of-ANDs predicates (#27627)
  • Skip downloading IPC batches exceeding slice bounds (#27683)
  • Avoid materializing broadcast list in list.shift (#27628)
  • Optimise json_decode Datetime string parsing (#27559)
  • Speed up to_numpy C-order via cache-blocked transpose (#27522)
  • Optimize select(len()) for non-strict horizontal concat (#27516)
  • Pushdown slices to inputs on left/right/full join (#27508)
  • Don't infer CSV schema if schema is set (#27507)
  • Nested common subplan elimination (#27340)
  • Make is_in row-group pruning precise on null-containing haystacks (#27495)
  • Don't do fused-multiply-add on scalars (#27479)
  • List full fast path (#27477)
  • Make is_in row-group pruning precise on multi-value lists (#27475)
  • Add streaming GatherNode (#27465)
  • Lower non-elementwise FunctionExprIR to ColumnarFunctionNode (#27462)
  • Speed up parquet metadata decode with hand-written Thrift (#27427)
✨ Enhancements
  • Use true division for the / operator in Polars SQL (#27391)
  • Add Rust backend for Expr.has_nulls (#27590)
  • Stabilize float16 (#27607)
  • Add Expr.is_empty (#27583)
  • Add support for the SQL FILTER clause for aggregate functions, and STRING_AGG (#27564)
  • Make parquet FileMetadata prunable for IR-plan dispatch (#27535)
  • Broadcast scalar input for list.slice (#27487)
  • Add LazyFrame.gather (#27501)
  • Add null_on_oob in {Expr/Series}.gather (#27327)
  • Stabilize streaming engine (#27497)
  • Process batched arr.eval on overflow boundaries (#27496)
  • Process batched list.eval on overflow boundaries (#27483)
  • Print SLICED UNION in LazyFrame explain (#27467)
🐞 Bug fixes
  • Panic in scan of empty IPC with slice (#27708)
  • Persist object_store rebuild state in cache (#27707)
  • Sort flag on GroupsType only applies to first element (#27684)
  • Invalid unwrap_unchecked when length isn't exact (#27685)
  • Don't unwrap channel send in streaming join_asof (#27688)
  • Fix merge_sorted panic when List in frame (#27568)
  • Put AsOf join buffered Morsels back the front of the deque if we cannot process them rn (#27658)
  • Fix skip_batches logic for NaN (#27673)
  • Raise TypeError when calling next() directly on GroupBy objects (#27562)
  • Data type comparison for extension types (#27632)
  • Share last-morsel split budget across files in streaming multi-scan (#27630)
  • Bytes scalars were not being broadcast in dataframe constructor (#27621)
  • Reset the sort-options in Series::is_sorted() after row-encoding columns (#27614)
  • Rayon deadlock with re-entrant io sources (#27600)
  • Don't push negative-offset slices through HConcat (#27570)
  • Logic error in streaming is_empty (#27602)
  • Fix incorrect CSE with large is_in literal (#27575)
  • AnonymousFunction can qualify as SQL aggregator (#26986)
  • Fix CSPE panic in cloud (#27594)
  • Set merge-join streaming node to Finished if its sending port is Done (#27572)
  • Widen decimal precision on sum aggregation at runtime (#27579)
  • Fix str.to_time was raising unnecessarily when input was all nulls (#27574)
  • Prevent panic when switching from one extension dtype to another (#27566)
  • Fix DataFrame.write_database(..., if_table_exists="append", engine="adbc") not handling missing tables correctly (#26913)
  • Ensure json_decode doesn't fail for Date and Time string deserialization (#27554)
  • Incorrect RUSTFLAGS passing in Makefile (#27555)
  • Fix panic on reading IPC with 0-row compressed bitmap (#27551)
  • Set HEAD_RESPONSE_SIZE_ESTIMATE to 0 (#27548)
  • Fix lazy concat horizontal didn't raise on mismatching heights after projection pushdown (#27506)
  • Prevent join panic when suffix="" and coalesce=True (#27376)
  • Do not make a FastCount for csv if pre_slice is set (#27536)
  • Support duplicate names in over (#27544)
  • Reassign sequence numbers when distributing input morsels in streaming AsOf join node (#27538)
  • Do not reverse dataframes when sorting with all-null key columns (#27517)
  • Incorrect length check on streaming zip (#27505)
  • Remove invalid type annotation Sequence[int] from DataFrame.\_\_setitem\_\_ key (#27355)
  • Respect nulls_last for descending over(order_by) in group_by().agg() (#27486)
  • Fix perf regression in scan_csv select(len()) when collected on streaming engine (#27504)
  • Harden extend strictness (#27476)
  • Prevent deadlock when using to_arrow() in a multithreaded context (#27472)
  • Do not flatten sliced union (#27466)
  • Prevent deadlock when using to_pandas() in multithreaded context (#27451)
  • Struct rechunk bug and add Series::with_validity (#27446)
  • Handle column indexing in read_parquet/read_csv with pyarrow reader (#27397)
  • Export enum as ordered dictionary to arrow (#27432)
  • Ensure sample() respects shuffle=False (#27248)
  • Return empty DataFrame from concat_list with lit and empty column (#27305)
  • Read parquet MAP columns without LogicalType annotation (#27404)
  • Raise DuplicateError on parquet files with duplicate column names (#27399)
📖 Documentation
  • Document Expr.list.__getitem__ (#27689)
  • Add cloudpickle requirement (#27703)
  • Clarify from_arrow schema ordering (#27493)
  • Fix a typo in join_asof docstring (#27682)
  • Clarify schema column order (#27681)
  • Document horizontal string concatenation (#27542)
  • Document all valid engine options on LazyFrame collect/sink/explain methods (#27374)
  • Orchestration docs check (#27605)
  • Drop redundant Pattern 2 from Dagster integration page (#27581)
  • Update to remove Dockerhub PAT references (#27582)
  • Modernize Dagster integration example for Polars Cloud (#27560)
  • Use Polars random seed in sample example (#27537)
  • Clarify full join description (#27530)
  • Make expressions operations RNG deterministic (#27494)
  • Document struct field order (#27492)
  • Improve over:order_by description (#27520)
  • Clarify join output columns (#27449)
  • Document null propagation in pl.format (#27447)
  • Document gzip support in read_csv (#27434)
  • Add See Also sections for datetime docstrings (#27316)
  • Polars On-Prem release (#27439)
  • Rename to Polars On-Prem (#27435)
  • Clarify null handling in unique operations (#27431)
  • Document write_ipc buffer behavior with file=None (#27430)
📦 Build system
  • Also split debug info in debug-release (#27609)
  • Use split-debuginfo on linux (#27608)
  • Bump deltalake to 1.5.1 in CI (#27387)
🛠️ Other improvements
  • Remove redundant DSL::AGG::Unique (#27718)
  • Harden against async blocking deadlocks (#27653)
  • Print Python traceback when POLARS_TIMEOUT_MS is exceeded (#27657)
  • Format missed in previous PR (#27700)
  • Bump pytest and remove codspeed (#27686)
  • Remove client-side allow_local_scans option for prepare_cloud_plan (#27663)
  • Remove superfluous test (#27676)
  • Cleanup streaming flags (#27671)
  • Expose unordered concatenation in python visitor (#27666)
  • Bump deltalake and fix CI (#27660)
  • Add impl IntoAExprBuilder for ExprIR (#27656)
  • Split _expand_selector_dicts into multiple functions so return type is simple and accurate (#27618)
  • Update object_store patch repo (#27650)
  • Match NumPy signature in DataFrame.__array__ and Series.__array__ (#27634)
  • Add ImageVersion to rust-cache key (#27626)
  • Run Pyrefly on tests (#27459)
  • Fix is_empty test (#27597)
  • Fix tz type difference pandas assert, take 2 (#27596)
  • Fix CSPE panic in cloud (#27594)
  • Fix tz type difference pandas assert (#27593)
  • Add contributing note about conventional comments (#27543)
  • Nested common subplan elimination (#27340)
  • Deduplicate interns (#27470)
  • Fix merge conflict in ColumnarFunction (#27464)
  • Keep the schema ordered in scan projection pushdown (#27429)
  • Remove unused type: ignore statements (#27360)
  • Remove redundant PhysNodeKind::AsOfJoin::{left_right}_by fields (#27400)
  • Resolve type-ignores in udfs.py (#27341)
  • Bump rustls-webpki (#27382)

Thank you to all our contributors for making this release possible! @0guban0v, @EndPositive, @JakubValtar, @Jesse-Bakker, @Kevin-Patyk, @Liyixin95, @MarcoGorelli, @NedJWestern, @Shoeboxam, @SuryaSunil1326, @TNieuwdorp, @alexander-beedie, @aryansri05, @ashler-herrick, @azimafroozeh, @carnarez, @coastalwhite, @dependabot[bot], @dsprenkels, @gab23r, @gautamvarmadatla, @ilya-pevzner, @jonathansergio, @junnythemarksman, @kdn36, @lun3x, @nameexhaustion, @orlp, @pablogsal, @ritchie46, @uurl, @waamm, @wence-, @wmoss, @xronocode and dependabot[bot]

View originalPermalink
How 1.41.0 went
1.40.1

Python Polars 1.40.1

Added 1
  • Add maintain_order parameter to merge_sorted
Changed 1
  • Skip validity mask processing in __array_ufunc__ when no inputs have nulls
Fixed 7
  • Honor having predicate in GroupBy iter
  • Use the physical dtype for NumUnorderedImplodeReducer arrow ListArray
  • Address bug in reduce_balanced for certain input length lists affecting pl.concat
  • Ensure list.sample() allows fraction > 1 when with_replacement=True
  • Ensure append() errors when upcast=False
  • Always rechunk sorts, prune sorts even in eager execution
  • Fix typing for DataFrame.__init__ and Series.__init__ so they don't require all optional dependencies to be installed
🚀 Performance improvements
  • Skip validity mask processing in __array_ufunc__ when no inputs have nulls (#27358)
✨ Enhancements
  • Cargo deny (#27363)
  • Add maintain_order parameter to merge_sorted (#27263)
🐞 Bug fixes
  • Honor having predicate in GroupBy iter (#27370)
  • Use the physical dtype for NumUnorderedImplodeReducer arrow ListArray (#27375)
  • Address bug in reduce_balanced for certain input length lists affecting pl.concat (#27352)
  • Ensure list.sample() allows fraction > 1 when with_replacement=True (#27350)
  • Ensure append() errors when upcast=False (#27346)
  • Always rechunk sorts, prune sorts even in eager execution (#27356)
  • Fix typing for DataFrame.__init__ and Series.__init__ so they don't require all optional dependencies to be installed (#27348)
📖 Documentation
  • Split out openlineage docs into guide and configuration (#27371)
  • Add explanation on the observatory sqlite db file (#27354)
🛠️ Other improvements
  • Disable mypy type checking for pyarrow calls (#27377)
  • Disable debug symbols in macos coverage tests (#27361)
  • Cargo deny (#27363)

Thank you to all our contributors for making this release possible! @EndPositive, @Kevin-Patyk, @MarcoGorelli, @carnarez, @dsprenkels, @gab23r, @jonathanchang31, @kdn36, @mzjp2 and @ritchie46

View originalPermalink
How 1.40.1 went
1.40.0

Python Polars 1.40.0

Added 5
  • Add streaming support for grouped AsOf join
  • Add `ignore_nulls` to `{list,arr}.{any,all}`
  • Add `is_unique` to list/array dtypes
  • Add `pl.merge_sorted` operating on multiple frames
  • Add native streaming `interpolate`
Changed 15
  • Create IR slice from expr slice pushdown
  • Avoid unnecessary rechunk when sorting already sorted DataFrame
  • Lower basic over() to streaming primitives
  • Lower `drop_{nulls,nans}` in streaming `group_by` aggregations
  • Lower `entropy` to streaming reductions
  • Streaming `strptime` with `format=None`
🏆 Highlights
  • Add streaming support for grouped AsOf join (#27293)
⚠️ Deprecations
  • Deprecate support for dataframe interchange protocol (#27214)
🚀 Performance improvements
  • Create IR slice from expr slice pushdown (#27200)
  • Add streaming support for grouped AsOf join (#27293)
  • Avoid unnecessary rechunk when sorting already sorted DataFrame (#27264)
  • Lower basic over() to streaming primitives (#27303)
  • Lower drop_{nulls,nans} in streaming group_by aggregations (#27296)
  • Lower entropy to streaming reductions (#27174)
  • Add native streaming interpolate (#27185)
  • Streaming strptime with format=None (#27056)
  • Lower skew / kurtosis to streaming aggregations (#27176)
  • Post apply pyarrow filter in Polars' engine instead of pyarrow (#27192)
  • Optimize drop_nulls().{first,last}() to {first,last}(ignore_nulls=True) (#27187)
  • Always process pyarrow scan in batches (#27183)
  • Make cut output Enum and mark as elementwise (#27173)
  • Remove unused expression sorts (#27075)
  • Use delta stats for mixed hive and non-hive predicate pushdown (#27102)
  • Take into account size per row in join sampling (#27098)
  • Streaming is_first_distinct and unique(maintain_order=True) (#27052)
  • Streaming cov and corr (#27008)
  • Add sorted unique node to streaming engine (#26990)
  • Ensure Expr.append is lowered in streaming engine (#27022)
  • Collapse consecutive Sort nodes (#26965)
  • Drop maintain_order=True requirement in sink_delta (#27007)
✨ Enhancements
  • Add ignore_nulls to {list,arr}.{any,all} (#27186)
  • Lock-free memory manager with spill-to-disk and fully OOC multiplexer (#26774)
  • Add is_unique to list/array dtypes (#27290)
  • Streaming pyarrow datasets sources (#27230)
  • Add pl.merge_sorted operating on multiple frames (#27014)
  • Allow group_by() without key exprs (#27141)
  • Change default scan/read_lines column name from "lines" to "line" (#27122)
  • Make unnest() effective on all columns by default (#27029)
  • Collapse consecutive Sort nodes (#26965)
🐞 Bug fixes
  • Update groups to correct length for Implode (#27282)
  • Fix scan_csv missing_columns='insert' overwrote existing data with NULLs (#27297)
  • Raise on non-numeric inputs in pl.int_ranges (#27294)
  • Fix always-true filter conversion to Iceberg filter (#27119)
  • Do not skip nulls when enumerating over rows in grouped AsOf join (#27275)
  • Fix pivot dropping data for null on values (#27273)
  • Resolve multiple files deadlock in CSV async reader (#27073)
  • Widen decimal precision on sum aggregation (#27270)
  • Correct lf.remote type (#27261)
  • Default LazyFrame.map_batches to no optimizations (#27262)
  • Extend StructEval schema context in StackOptimizer (#27243)
  • Preserve nulls when casting from all-null Series to Struct (#27241)
  • Fix scan_delta filter on empty dataframe (#27244)
  • Prevent DataFrame creation panic on list[struct] with heterogenous types (#27217)
  • Named aggregation __structify was being ignored (#27148)
  • Skip null group entries when collecting AsOf-by groups (#27215)
  • Fix panic with empty order_by in over expression (#27088)
  • Write field ID from sink_parquet (#27196)
  • Fix statistics for Null columns in Parquet (#27021)
  • Do not prune sort nodes containing slice with dyn predicate (#27140)
  • Correct grouped Binary arg_min/arg_max and String single-element arg indices (#27172)
  • Resolve multiple files deadlock in NDJSON async reader (#27204)
  • Overflow panic in interpolate nearest (#27205)
  • Using checked arithmetic in int96_to_i64_ns to prevent overflow panic (#27129)
  • Don't trigger csv fast count if predicate is pushed down (#27190)
  • Support all integer dtypes for Series index assignment (#27188)
  • Streaming sort by-expressions were lowered incorrectly (#27158)
  • Replace multiprocessing.dummy.Pool with ThreadPoolExecutor (#27175)
  • Reset IO metrics instead of consuming (#27156)
  • Output SVG if output_path ends with '.svg' in show_graph (#27144)
  • Skip extension types for min/max in describe (#27120)
  • Address a potential overflow in from_epoch scaling (#27118)
  • Fix incorrect IO metrics on multi-phase streaming execution (#27123)
  • Use delta stats for mixed hive and non-hive predicate pushdown (#27102)
  • Make the files used in docs available locally (#27121)
  • Apply scalar bound in clip when the Series bound contains nulls (#27087)
  • Ignore ddof parameter in rolling_corr and deprecate (#27104)
  • Preserve casts for horizontal ops with untyped literals (#27011)
  • Reject invalid input to sql_expr (#27084)
  • Ensure SQL COUNT(<lit>) expressions return the correct value (#27085)
  • Regression in replace_strict for enums (#27066)
  • Make test_group_by_arg_max_boolean_26978 non-flaky for max_by ties (#27048)
  • Null count for aggregated list inside count aggregation (#27032)
  • Panic in streaming MergeSortedNode (#27024)
  • Prevent panic in transpose() with mixed List and non-List columns (#27038)
  • Set sorted flag for Boolean and Time (#27035)
  • Missing src/ subdirectory to CI Python docs step (#27025)
  • Resolve stack overflow on merge_sorted and union (#27018)
  • Make pl.DataFrame.fill_null work on columns with Null dtype (#27020)
  • Fix repeated word typos in comments (#26917)
  • Covariance with constant is zero, not NaN (#27015)
  • Don't remove set_sorted in projection pushdown (#27006)
  • Infer nulls when df create from empty-struct (#26991)
  • Correct suggestion in multi-expr filter error (#27003)
  • Implement agg_arg_min/agg_arg_max for boolean data type (#26997)
  • Ensure sample() respects the global set seed (#26992)
📖 Documentation
  • Add documentation for openlineage on-premises (#27334)
  • Release page (#27335)
  • Update uv pip install polars-on-premises cmd (#27330)
  • Fix outdated LazyGroupBy.map_groups docstring (#27292)
  • Add deny_anonymous_users to scheduler config (#27287)
  • Slurm documentation (#27259)
  • Add link to concepts in index.md (#27077)
  • Add docs entry for merge_sorted (#27224)
  • Fix typo (#27212)
  • Make the files used in docs available locally (#27121)
  • Put first-time contribution requirements in its own linkable section (#27113)
  • Add missing docstrings for Expr.struct.__getitem__ and Series.__setitem__ (#27092)
  • Normalise Series docstring whitespace indents (#27082)
  • Change Polars Cloud API to 0.6.0 (#27005)
  • Improve write_parquet docstring for use_pyarrow (#26988)
📦 Build system
  • Really do not install pyiceberg-core 0.9.0 (#27017)
🛠️ Other improvements
  • Add regression test for instantiating polars DataFrame from pandas Timestamp (#27332)
  • Bump Python Polars version (#27315)
  • Resolve bad instantiations in test_iceberg (#27314)
  • Sink DSL and callback for Iceberg (#27258)
  • Wait for morsel consumption in merge_sorted streaming node (#27288)
  • Use more precise internal typing (pt. iii) (#27232)
  • Mark scan_ipc cache arguments as deprecated (#27216)
  • Consolidate reordered compare functions (#27229)
  • Fix test_dtype_concat_3735 not actually iterating through numeric dtypes (#27178)
  • Remove dead code in test_scan_lines (#27213)
  • Move/genericize _balanced_reduce to Python utils (#27100)
  • Remove unused attributes (#27191)
  • Avoid unnecessary recompilation due to changing env vars (#27166)
  • Update nightly Rust compiler version (#27145)
  • Simplify pyarrow scan and process in batches (#26982)
  • Make internal typing more precise (part ii) (#27117)
  • Add None & Dataframe to FrameInitTypes (#27126)
  • Remove unused expression sorts (#27075)
  • Improve internal typing ahead of using ty / pyrefly (#27050)
  • Add explicit ResourceWarning coverage (#27083)
  • Add sinked paths callback (#26995)
  • Pin maturin due to compile time regression (#27062)
  • Missing src/ subdirectory to CI Python docs step (#27025)
  • Really do not install pyiceberg-core 0.9.0 (#27017)
  • Naming for named scopes (#26999)
  • Enable hypothesis tests when POLARS_AUTO_NEW_STREAMING=1 (#26818)
  • Fix CI by excluding missing wheel version of pyiceberg (#27001)
  • Remove indirection in calling python scans (#26981)
  • Polars versions (#26980)

Thank you to all our contributors for making this release possible! @0xRozier, @EndPositive, @HCYT, @Kevin-Patyk, @MarcoGorelli, @NeejWeej, @RedZapdos123, @TNieuwdorp, @abhidotsh, @alexander-beedie, @andyjessen, @azimafroozeh, @borchero, @carnarez, @coastalwhite, @debnathshoham, @dpinol, @dsprenkels, @dydev012, @farouk-01, @gab23r, @gautamvarmadatla, @joaquinhuigomez, @kdn36, @nameexhaustion, @orlp, @ritchie46, @wence-, @xenzh, @yangsong97 and @yonatan-genai

View originalPermalink
How 1.40.0 went
1.39.3

Python Polars 1.39.3

  • No changes

Thank you to all our contributors for making this release possible! @ritchie46

View originalPermalink
How 1.39.3 went
1.39.2

Python Polars 1.39.2

  • No changes

Thank you to all our contributors for making this release possible! @nameexhaustion and @ritchie46

View originalPermalink
How 1.39.2 went
1.39.1

Python Polars 1.39.1

Fixed 1
  • Handle empty rolling windows in streaming engine
🐞 Bug fixes
  • Handle empty rolling windows in streaming engine (#26903)
📖 Documentation
  • Add documentation for on_columns for LazyFrame pivot (#26859)
🛠️ Other improvements
  • Bump build deps used in ARM64 Windows release pipeline (#26892)

Thank you to all our contributors for making this release possible! @Kevin-Patyk, @RenzoMXD, @TNieuwdorp, @dsprenkels, @gautamvarmadatla, @nameexhaustion, @nicholaslegrand102 and @ritchie46

View originalPermalink
How 1.39.1 went
1.39.0

Python Polars 1.39.0

Added 4
  • Support Expr for holidays in business day calculations
  • Parameter for pivot to always include value column name
  • Extend Expr.reinterpret to all numeric types of the same size
  • Add missing_columns parameter to scan_csv
Changed 16
  • Lower arg_{min,max} to streaming engine
  • Additional IR slice pushdown after filter pushdown
  • Streaming first/last on Enum through physical
  • Fast filter for scalar predicates
  • Allow SimpleProjection in streaming engine to rename
  • Streaming cloud download for scan_csv
🚀 Performance improvements
  • Lower arg_{min,max} to streaming engine (#26845)
  • Additional IR slice pushdown after filter pushdown (#26815)
  • Streaming first/last on Enum through physical (#26783)
  • Fast filter for scalar predicates (#26745)
  • Allow SimpleProjection in streaming engine to rename (#26709)
  • Streaming cloud download for scan_csv (#26637)
  • Drop columns only needed for predicates after the predicate is applied (#26703)
  • Run projection pushdown after predicate pushdown (#26688)
  • Comparison literal downcasting (#26663)
  • Add dynamic predicates for TopK (#26495)
  • Increase minimum default parquet row group prefetch to 8 (#26632)
  • Partial predicate conversion to PyArrow (#26567)
  • Streaming cloud download for scan_ndjson / scan_lines (#26563)
  • Grab GIL fewer times during Object join materialization (#26587)
  • Improve CSV and NDJSON cloud sink performance (#26545)
  • Tune cloud writer performance (#26518)
  • Allow parallel InMemorySinks in streaming engine (#26501)
  • Add streaming AsOf join node (#26398)
  • Don't always rechunk on gather of nested types (#26478)
✨ Enhancements
  • Support Expr for holidays in business day calculations (#26193)
  • Parameter for pivot to always include value column name (#26730)
  • Raise error in .collect_schema() when arr.get() is out-of-bounds (#26866)
  • Extend Expr.reinterpret to all numeric types of the same size (#26401)
  • Add missing_columns parameter to scan_csv (#26787)
  • Clear no-op scan projections (#26858)
  • Support nested datatypes for {min,max}_by (#26849)
  • Support SQL ARRAY init from typed literals (#26622)
  • Accept table identifier string in scan_iceberg() (#26826)
  • Add a convenience make fresh command to the Makefile (#26809)
  • Expose "use_zip64" Workbook option for write_excel (#26699)
  • Add unstable LazyFrame.sink_iceberg (#26799)
  • Add maintain order argument on implode (#26782)
  • Speed up casting primitive to bool by at least 2x (#26823)
  • Support ASCII format table input to pl.from_repr (#26806)
  • Enable rowgroup skipping for float columns (#26805)
  • Add expression context to errors (#26716)
  • Add Decimal support for product reduction (#26725)
  • Support all Iceberg V2 arrow types in sink_parquet arrow_schema parameter (#26669)
  • Re-work behavior of arrow_schema parameter on sink_parquet (#26621)
  • Add contains_dtype() method for Schema (#26661)
  • Implement truncate as a "to_zero" rounding mode (#26677)
  • More generic streaming GroupBy lowering (#26696)
  • Create an Alignment TypeAlias (#26668)
  • Add basic MemoryManager to track buffered dataframes for out-of-core support later (#26443)
  • Add truncate Expression for numeric values (#26666)
  • Better error messages for hex literal conversion issues in the SQL interface (#26657)
  • Add SQL support for LPAD and RPAD string functions (#26631)
  • Support SQL "FROM-first" SELECT query syntax (#26598)
  • Improve base_type typing (#26602)
  • Bump Chrono to 0.4.24, enabling stricter parsing of %.3f/%.6f/%.9f specifiers (#26075)
  • Expose unstable assert_schema_equal in py-polars (#24869)
  • Allow parsing of compact ISO 8601 strings (#24629)
  • Add optional "label" param to DataFrame corr (#26588)
  • Streaming cloud download for scan_ndjson / scan_lines (#26563)
  • Configuration to cast integers to floats in cast_options for scan_parquet (#26492)
  • Add escaping to quotes and newlines when reading JSON object into string (#26578)
  • Standardise on RFC-5545 when doing datetime arithmetic on timezone-aware datetimes (#26425)
  • Support sas_token in Azure credential provider (#26565)
  • Relax SQL requirement for derived tables and subqueries to have aliases (#26543)
  • Add polars-config and pl.Config.reload_env_vars() (#26524)
  • Record path for object store error raised from sinks (#26541)
  • Use CRC64NVME for checksum in aws sinks (#26522)
  • Add get() for binary Series (#26514)
  • Add streaming AsOf join node (#26398)
  • Add primitive filter -> agg lowering in streaming GroupBy (#26459)
  • Support for the SQL FETCH clause (#26449)
🐞 Bug fixes
  • Prevent Boolean arithmetic with integer literals producing Unknown type in streaming engine (#26878)
  • Fix sink to partitioned S3 from Windows corrupted slashes (#26889)
  • Remove outdated warning about List columns in unique() (#26295) (#26890)
  • Restore pyarrow predicate conversion for is_in (#26811)
  • Release GIL before df.to_ndarray() to avoid deadlock (#26832)
  • Fix panic on CSV count_rows with FORCE_ASYNC (#26883)
  • Add scalar comparisons for UInt128 series (#26886)
  • Fix shape error not raised for 0 width inputs with non-0 height for streaming horizontal concat (#26877)
  • Fix streaming zip-broadcast node did not raise shape mismatch on empty recv from ready port (#26871)
  • Fix incorrect output list.eval with scalar expr, fix panic on list.agg with nulls (#26868)
  • Allow list argument in group_by().map_groups() (#26707)
  • Support for ADBC drivers instantiated with dbc in DataFrame.write_database (#26157)
  • Incorrect arg_sort with descending+limit (#26839)
  • Raise error in .collect_schema() when arr.get() is out-of-bounds (#26866)
  • Return ComputeError instead of panicking in map_groups UDF (#26665)
  • Issue PerformanceWarning in LazyFrame.__contains__ (#26734)
  • Correct type hint for map_columns function parameter (#26487)
  • Apply thousands_separator to count/null_count in describe() for non-numeric columns (#26486)
  • Ensure proper handling of timedelta when multiplying with a Series (#26830)
  • Correct type hint for function parameter in DataFrame.map_columns (#26372)
  • Segfault in JoinExec on deep plan (#26796)
  • Fix unary expressions on literal in over context (#26827)
  • Fix {min,max}_by in streaming engine for Boolean full {min,max} value column (#26848)
  • Fix debug panic on clip with nan bound (#26854)
  • Support grouped {arg_,}_{min,max} for Categoricals (#26856)
  • Throw an error if a string is passed to LazyFrame.pivot on_columns (#26852)
  • Preserve input float precision in rolling_cov() and rolling_corr() with mixed input types (#26820)
  • Preserve row count when converting zero-column DataFrame via arrow PyCapsule interface (#26835)
  • Prevent infinite recursion in streaming group_by fallback (#26801)
  • Use RowEncodingContext::Struct when determining D::Struct encoded item len (#26817)
  • Incorrectly applied CSE on different map_batches functions (#26822)
  • Fix duplicated query execution on todo panic when combining collect(engine='streaming') with POLARS_AUTO_NEW_STREAMING (#26792)
  • Prevent predicate pushdown across Sort with baked-in slice (#26804)
  • Restore compatibility with pd.Timedelta (#26785)
  • Fix panic on lazy sink_parquet created in pipe_with_schema (#26784)
  • Support {column_name} and {index} placeholders in pl.format string (#26771)
  • Do not use merge-join if nulls_last is unknown (#26778)
  • Normalize float zeros in Parquet column statistics (#26776)
  • Fix out-of-bounds for positive offset in windowed rolling (#26724)
  • Raise error when .get() is out-of-bounds in group by context (#26752)
  • Boolean bitwise_xor aggregation inverted when column contains nulls (#26749)
  • Parameter nulls_last was ignored in over (#26718)
  • Allow missing time in inexact strptime (#26714)
  • Respect nulls_last in sort_by within group_by().agg() slow path (#26681)
  • Return NaN when using corr() with a literal and expr (#26697)
  • Allow strict horizontal concat with empty df (#26345)
  • Fix PoisonError panic caused by reentrant usage of file cache (#26627)
  • Return null for int values exceeding 128-bit range with strict=False (#26674)
  • Incorrect boolean min/max with nulls (#26671)
  • Slice-slice pushdown for n_rows (#26673)
  • Resolve panic in Enum struct slicing (#26643)
  • Fix CSPE for group_by.map_groups (#26640)
  • Remove non-existent parameter from SQLContext typing overloads (#26658)
  • Address pl.from_epoch losing fractional seconds (#26419)
  • Fix to_pandas() on empty enum Series did not preserve enum dictionary (#26610)
  • Rounding behaviour for f32 values with "HalfAwayFromZero" mode (#26624)
  • Updated Sum Type Hint (#26629)
  • Don't allow namespace registration to override standard methods or properties (#26450)
  • Correct arg_(min|max) for scalar columns (#26609)
  • Use monkeypatch.chdir in test_sink_path_slicing_utf8_boundaries_26324 (#26616)
  • Respect SQL semantics for cumulative functions mapped via OVER clause (#26570)
  • Fix incorrect multiplexer output ordering on source token stop request (#26561)
  • Fix PyIceberg filter on boolean column (#26550)
  • Set dictionary_page_offset when dictionary encoding is used and point data_page_offset to the first data page (#26542)
  • Move query parameters to request body when retrieving Unity Catalog temporary credentials (#26539)
  • Ensure read_csv_batched() prints deprecation warning (#26530)
  • Implement PhysicalExpr for MinBy/MaxBy nodes (#26506)
  • Refactor row-encoding logic in IR join lowering into separate function (#26512)
  • Correctly check for path extensions (#26513)
  • Change AsOf join to be based on TotalOrd (#26497)
  • Correctly raise error on failing nested strict casts (#26499)
  • Prevent invalid type casts in replace_strict() (#26453)
  • Return null when dividing literals by 0 (#26343)
  • Fix type-hint for Series.quantile (#26422)
📖 Documentation
  • Mention ComputeContexts create ephemeral environments by default and hint at re-use (#26692)
  • Remove confusing join validation note (#26795)
  • Fix formatting in categorical documentation (#26746)
  • Fix broken AI policy link (#26728)
  • Create Polars Cloud Glossary (#26690)
  • Additional SQL documentation (#26662)
  • Include invalidate_caches in bisect instructions (#26641)
  • Add git bisect guide to contributing docs (#26634)
  • Fix Polars Cloud examples (formatting & type hints) (#26625)
  • Updated Airflow orchestration documentation (#26585)
  • Improve SQL docs for EXTRACT and DATE_PART functions (#26575)
  • Fix docstring for bitwise_count_zeros method (#26519)
  • Add get() for binary Series (#26514)
🛠️ Other improvements
  • Use large linux-arm runner for release (#26898)
  • Ensure .gitignore and .typos.toml exclude "_polars_runtime*" directories (#26842)
  • Additional IR slice pushdown after filter pushdown (#26815)
  • Add private _expand_paths scan function (#26798)
  • Change Expr sortedness container to AExprSorted and add nulls_last to PyExpr.set_sorted() (#26781)
  • Move stop_and_buffer_pipe_contents into joins/utils.rs (#26810)
  • Replace iejoin is_supported_type macro with a closure in predicate_pushdown/join.rs (#26812)
  • Fix first-time contributor auto-label (#26794)
  • Automatically add first-contribution label (#26780)
  • Add tests for functions that operate on pl.all() expansion (#26773)
  • Make contributing policy more strict (#26772)
  • Add unused argument warning to ruff rules (#26720)
  • Move shared streaming CSV/NDJSON code into shared mod (#26742)
  • Undo pub removal of to_dyn_object_store (#26722)
  • Mark {read, scan}_ndjson cache argument(s) as deprecated (#26711)
  • Add test for predicate before join (#26705)
  • Remove PlanCallback from sql (#26686)
  • Bump Rust nightly compiler version (#26379)
  • Remove unused problematic ArrayFromIter (#26639)
  • Move more boolean code to polars_compute, reusing kernels (#26636)
  • Avoid implicit import from importlib (#26603)
  • Cleanup assert_schema_equal (#26596)
  • Replace some env var reading by polars-config (#26607)
  • Use monkeypatch.chdir in test_sink_path_slicing_utf8_boundaries_26324 (#26616)
  • Add __init__.py files and docstrings to testing directories (#26408)
  • Add wrapper for clippy so it continues on warnings (#26527)
  • Use LazyFrame.clear to clear sql (#26562)
  • Update docs (#26560)
  • Add backtrace coloring (#26544)
  • Evaluate sql process_except_intersect during IR (#26516)
  • Reformat LICENSE (#26532)
  • Add a pipeline in which we test with POLARS_IDEAL_MORSEL_SIZE=4 (#26420)
  • Remove test_file and have tests create test.parquet in tmp_path (#26525)
  • Refactor row-encoding logic in IR join lowering into separate function (#26512)
  • Fix mypy pyiceberg expression errors (#26523)
  • Make nix flake mostly work (#26517)
  • Switch to custom cloud writer with IO sink metrics (#26494)
  • Update s3fs dev dependency (#26509)
  • Remove Default on DataType (#26511)
  • Have parameterized series rechunk() if not allow_chunks (#26504)
  • Remove dead code (RevMapping) (#26508)
  • Upgraded ruff, mypy, typos (#26476)
  • More SQL to IR conversion execute_isolated (#26455)

Thank you to all our contributors for making this release possible! @BJohnBraddock, @EndPositive, @Jesse-Bakker, @Kevin-Patyk, @MarcoGorelli, @Matt711, @NathanHu725, @RenzoMXD, @TNieuwdorp, @Voultapher, @WaffleLapkin, @abishop1990, @alexander-beedie, @azimafroozeh, @boris324, @cBournhonesque, @carnarez, @coastalwhite, @daizutabi, @dependabot[bot], @dsprenkels, @erandagan, @etiennebacher, @gautamvarmadatla, @henryharbeck, @hutch3232, @itamarst, @jberg5, @johalnes, @kdn36, @leudz, @lukas-reining, @moktamd, @mqqz, @mroeschke, @nameexhaustion, @orlp, @pragun-ananda, @qxzcode, @ritchie46, @spock-yh, @stakeswky, @tlauli, @toroleapinc, @veeceey and dependabot[bot]

View originalPermalink
How 1.39.0 went
1.38.1

Python Polars 1.38.1

Added 1
  • Add get() to retrieve a byte from binary data
Changed 1
  • Remove with_context in SQL lowering
Fixed 12
  • Do not overwrite used names in cluster_with_columns pushdown
  • Do not mark output of concat_str on multiple inputs as sorted
  • Fix CSV schema inference content line duplication bug
  • Fix InvalidOperationError using scan_delta with filter
  • Alias giving missing column after streaming GroupBy CSE
  • Ensure by_name selector selects only names
✨ Enhancements
  • Add get() to retrieve a byte from binary data (#26454)
  • Remove with_context in SQL lowering (#26416)
🐞 Bug fixes
  • Do not overwrite used names in cluster_with_columns pushdown (#26467)
  • Do not mark output of concat_str on multiple inputs as sorted (#26468)
  • Fix CSV schema inference content line duplication bug (#26452)
  • Fix InvalidOperationError using scan_delta with filter (#26448)
  • Alias giving missing column after streaming GroupBy CSE (#26447)
  • Ensure by_name selector selects only names (#26437)
  • Restore compatibility of strings written to parquet with pyarrow filter (#26436)
  • Update schema in cluster_with_columns optimization (#26430)
  • Fix negative slice in groups slicing (#26442)
  • Don't run CPU check on aarch64 musl (#26439)
  • Fixed annotations shadowed by class methods (#26356)
  • Remove the POLARS_IDEAL_MORSEL_SIZE monkeypatching in the parametric merge-join test (#26418)
  • Fix selector match patterns for multiline column names (#26320)
📖 Documentation
  • Add sink_delta to API reference (#26446)
🛠️ Other improvements
  • Cleanup unused attributes in optimizer (#26464)
  • Use Expr::Display as catch all for IR - DSL asymmetry (#26471)
  • Ignore pytz in mypy (#26441)
  • Remove the POLARS_IDEAL_MORSEL_SIZE monkeypatching in the parametric merge-join test (#26418)
  • Cleanup the parametric merge-join test (#26413)

Thank you to all our contributors for making this release possible! @Voultapher, @alexander-beedie, @azimafroozeh, @cmdlineluser, @dependabot[bot], @dsprenkels, @hamdanal, @kdn36, @nameexhaustion, @orlp, @ritchie46 and dependabot[bot]

View originalPermalink
How 1.38.1 went
1.38.0

Python Polars 1.38.0

Added 8
  • Add streaming merge-join
  • Support anonymous agg in-mem
  • Add unstable arrow_schema parameter to sink_parquet
  • Allow quantile to compute multiple quantiles at once
  • Allow empty LazyFrame in LazyFrame.group_by(...).map_groups
  • Add scan_lines
  • Support regex in str.split
  • Add nulls support for all rolling_by operations
Changed 11
  • Enable zero-copy object_store put upload for IPC sink
  • Resolve file schema's and metadata concurrently
  • Run elementwise CSEE for the streaming engine
  • Disable morsel splitting for fast-count on streaming engine
  • Implement streaming decompression for scan_ndjson and scan_lines
  • Improve string slicing performance
Fixed 1
  • Avoid OOM for scan_ndjson and scan_lines if input is compressed and negative slice
Deprecated 1
  • Deprecate retries=n in favor of storage_options={"max_retries": n}
⚠️ Deprecations
  • Deprecate retries=n in favor of storage_options={"max_retries": n} (#26155)
🚀 Performance improvements
  • Enable zero-copy object_store put upload for IPC sink (#26288)
  • Resolve file schema's and metadata concurrently (#26325)
  • Run elementwise CSEE for the streaming engine (#26278)
  • Disable morsel splitting for fast-count on streaming engine (#26245)
  • Implement streaming decompression for scan_ndjson and scan_lines (#26200)
  • Improve string slicing performance (#26206)
  • Refactor scan_delta to use python dataset interface (#26190)
  • Add dedicated kernel for group-by arg_max/arg_min (#26093)
  • Add streaming merge-join (#25964)
  • Generalize Bitmap::new_zeroed opt for Buffer::zeroed (#26142)
  • Reduce fs stat calls in path expansion (#26173)
  • Lower streaming group_by n_unique to unique().len() (#26109)
✨ Enhancements
  • Avoid OOM for scan_ndjson and scan_lines if input is compressed and negative slice (#26396)
  • Support annoymous agg in-mem (#26376)
  • Add unstable arrow_schema parameter to sink_parquet (#26323)
  • Improve error message formatting for structs (#26349)
  • Remove parquet field overwrites (#26236)
  • Enable zero-copy object_store put upload for IPC sink (#26288)
  • Improved disambiguation for qualified wildcard columns in SQL projections (#26301)
  • Expose upload_concurrency through env var (#26263)
  • Allow quantile to compute multiple quantiles at once (#25516)
  • Allow empty LazyFrame in LazyFrame.group_by(...).map_groups (#26275)
  • Use delta file statistics for batch predicate pushdown (#26242)
  • Add streaming UnorderedUnion (#26240)
  • Implement compression support for sink_ndjson (#26212)
  • Add unstable record batch statistics flags to {sink/scan}_ipc (#26254)
  • Support CSE for python UDFs on the same address (#26253)
  • Cloud retry/backoff configuration via storage_options (#26204)
  • Use same sort order for expanded paths across local / cloud / directory / glob (#26191)
  • Add streaming merge-join (#25964)
  • Serialize optimization flags for cloud plan (#26168)
  • Add compression support to write_csv and sink_csv (#26111)
  • Add scan_lines (#26112)
  • Support regex in str.split (#26060)
  • Add unstable IPC Statistics read/write to scan_ipc/sink_ipc (#26079)
  • Add unstable height parameter to DataFrame/LazyFrame (#26014)
  • Remove old partition sink API (#26100)
  • Expose ArrowStreamExportable on python collect batches iterator (#26074)
  • Add nulls support for all rolling_by operations (#26081)
🐞 Bug fixes
  • Correct off-by-one in RLE row counting for nullable dictionary-encoded columns (#26411)
  • Support very large integers in env var limits (#26399)
  • Fix PlPath panic from incorrect slicing of UTF8 boundaries (#26389)
  • Fix Float dtype for spearman correlation (#26392)
  • Fix optimizer panic in right joins with type coercion (#26365)
  • Don't serialize retry config from local environment vars (#26289)
  • Fix PartitionBy with scalar key expressions and diff() (#26370)
  • Add {Float16, Float32} -> Float32 lossless upcast (#26373)
  • Fix panic using with_columns and collect_all (#26366)
  • Add multi-page support for writing dictionary-encoded Parquet columns (#26360)
  • Ensure slice advancement when skipping non-inlinable values in is_in with inlinable needles (#26361)
  • Pin xlsx2csv version temporarily (#26352)
  • Bugs in ViewArray total_bytes_len (#26328)
  • Overflow in i128::abs in Decimal fits check (#26341)
  • Make Expr.hash on Categorical mapping-independent (#26340)
  • Clone shared GroupBy node before mutation in physical plan creation (#26327)
  • Fixed "sheet_name" typing for read_ods and read_excel (#26317)
  • Improve Polars dtype inference from Python Union typing (#26303)
  • Consider the "current location" of an item when computing rolling_rank_by (#26287)
  • Reset is_count_star flag between queries in collect_all (#26256)
  • Fix incorrect is_between filter on scan_parquet (#26284)
  • Make polars compatible with ty (#26270)
  • Lower AnonymousStreamingAgg in group-by as aggregate (#26258)
  • Avoid overflow in pl.duration scalar arguments case (#26213)
  • Broadcast arr.get on single array with multiple indices (#26219)
  • Fix panic on CSPE with sorts (#26231)
  • Eager DataFrame.slice with negative offset and length=None (#26215)
  • Use correct schema side for streaming merge join lowering (#26218)
  • Overflow panic in scan_csv with multiple files and skip_rows + n_rows larger than total row count (#26128)
  • Respect allow_object flag after cache (#26196)
  • Raise error on non-elementwise PartitionBy keys (#26194)
  • Allow ordered categorical dictionary in scan_parquet (#26180)
  • Allow excess bytes on IPC bitmap compressed length (#26176)
  • Address a macOS-specific compile issue (#26172)
  • Fix deadlock on hash_rows() of 0-width DataFrame (#26154)
  • Fix NameError filtering pyarrow dataset (#26166)
  • Fix concat_arr panic when using categoricals/enums (#26146)
  • Fix NDJSON/scan_lines negative slice splitting with extremely long lines (#26132)
  • Incorrect group_by min/max fast path (#26139)
  • Remove a source of non-determinism from lowering (#26137)
  • Error when with_row_index or unpivot create duplicate columns on a LazyFrame (#26107)
  • Panics on shift with head (#26099)
📖 Documentation
  • Fix Expr.get referencing incorrect dtype for index parameter (#26364)
  • Fix Expr.quantile formatting (#26351)
  • Drop sphinx-llms-txt extension (#26285)
  • Remove deprecated cublet_id (#26260)
  • Update for new release (#26255)
  • Update MCP server section with new URL (#26241)
  • Fix unmatched paren and punctuation in pandas migration guide (#26251)
  • Add observatory database_path to docs (#26201)
  • Note plugins in Python user-defined functions (#26138)
📦 Build system
  • Address remaining Python 3.14 issues with make requirements-all (#26195)
  • Address a macOS-specific compile issue (#26172)
🛠️ Other improvements
  • Ensure local doctests skip from_torch if module not installed (#26405)
  • Change linked timezones in test suite to canonical timezones (#26310)
  • Implement various deprecations (#26314)
  • Rename Operator::Divide to RustDivide (#26339)
  • Properly disable the Pyodide tests (#26382)
  • Remove unused field (#26367)
  • Fix runtime nesting (#26359)
  • Remove xlsx2csv dependency pin (#26355)
  • Use outer runtime if exists in to_alp (#26353)
  • Make CategoricalMapping::new pub(crate) to avoid misuse (#26308)
  • Clarify IPC buffer read limit/length paramter (#26334)
  • Add dtype test coverage for delta predicate filter (#26291)
  • Add AI policy (#26286)
  • Unpin "pandas<3" in dev dependencies (#26249)
  • Remove all non CSV fast-count paths (#26233)
  • Pin pandas to 2.x for now (#26221)
  • Remove unnecessary xfail (#26199)
  • Ensure optimization flag modification happens local (#26185)
  • Simplify IcebergDataset (#26165)
  • Reorganize unit tests into logical subdirectories (#26149)
  • Lint leftover fixme (#26122)
  • Improve backtrace for POLARS_PANIC_ON_ERR (#26125)
  • Fix Python docs build (#26117)
  • Disable unused-ignore mypy lint (#26110)
  • Ignore mypy warning (#26105)
  • Raise error on file://hostname/path (#26061)
  • Disable debug info for docs workflow (#26086)
  • Update docs for next polars cloud release (#26091)
  • Support Python 3.14 in dev environment (#26073)

Thank you to all our contributors for making this release possible! @Atarust, @EndPositive, @Kevin-Patyk, @LeeviLindgren, @MarcoGorelli, @Matt711, @MrAttoAttoAtto, @Voultapher, @WaffleLapkin, @agossard, @alex-gregory-ds, @alexander-beedie, @azimafroozeh, @bayoumi17m, @c-peters, @carnarez, @dependabot[bot], @dsprenkels, @hallmason17, @hamdanal, @ion-elgreco, @kdn36, @lun3x, @mcrumiller, @nameexhaustion, @orlp, @qxzcode, @r-brink, @ritchie46, @sweb and dependabot[bot]

View originalPermalink
How 1.38.0 went
1.37.1

Python Polars 1.37.1

Changed 1
  • Speed up SQL interface UNION clauses
Fixed 4
  • Optimize slicing support on compressed IPC
  • CPU check for musl builds
  • Propagate C Stream import errors instead of panicking
  • Fix slicing on compressed IPC
🚀 Performance improvements
  • Speed up SQL interface "UNION" clauses (#26039)
🐞 Bug fixes
  • Optimize slicing support on compressed IPC (#26071)
  • CPU check for musl builds (#26076)
  • Propagate C Stream import errors instead of panicking (#26036)
  • Fix slicing on compressed IPC (#26066)
📖 Documentation
  • Clarify min_by/max_by behavior on ties (#26077)
🛠️ Other improvements
  • Mark top slow normal tests as slow (#26080)
  • Update breaking deps (#26055)
  • Fix for upstream url bug and update deps (#26052)
  • Properly pin chrono (#26051)
  • Don't run rust doctests (#26046)
  • Update deps (#26042)
  • Ignore very slow test (#26041)

Thank you to all our contributors for making this release possible! @Voultapher, @alexander-beedie, @kdn36, @nameexhaustion, @orlp, @ritchie46 and @wtn

View originalPermalink
How 1.37.1 went
1.37.0

Python Polars 1.37.0

Added 10
  • Add new pl.PartitionBy API
  • Add lazy collect_all
  • Add nulls support for rolling_mean_by
  • Expose record batch size in {sink,write}_ipc
  • Add null_on_oob parameter to expr.get
  • Support streaming IPC scan from S3 object store
Changed 8
  • Speed up SQL interface ORDER BY clauses
  • Add fast kernel for is_nan and use it for numpy NaN->null conversion
  • New streaming NDJSON sink pipeline
  • New streaming CSV sink pipeline
  • Replace ryu with faster zmij
  • Use new sink pipeline for write/sink_ipc
  • Improve handling of unqualified SQL JOIN columns that are ambiguous
  • Drop Python 3.9 support
Fixed 2
  • Make struct.with_fields data model coherent
  • Ensure chunk consistency in in-memory join
🚀 Performance improvements
  • Speed up SQL interface "ORDER BY" clauses (#26037)
  • Add fast kernel for is_nan and use it for numpy NaN->null conversion (#26034)
  • Optimize ArrayFromIter implementations for ObjectArray (#25712)
  • New streaming NDJSON sink pipeline (#25948)
  • New streaming CSV sink pipeline (#25900)
  • Dispatch partitioned usage of sink_* functions to new-streaming by default (#25910)
  • Replace ryu with faster zmij (#25885)
  • Reduce memory usage for .item() count in grouped first/last (#25787)
  • Skip schema inference if schema provided for scan_csv/ndjson (#25757)
  • Add width-aware chunking to prevent degradation with wide data (#25764)
  • Use new sink pipeline for write/sink_ipc (#25746)
  • Reduce memory usage when scanning multiple parquet files in streaming (#25747)
  • Don't call cluster_with_columns optimization if not needed (#25724)
✨ Enhancements
  • Add new pl.PartitionBy API (#26004)
  • ArrowStreamExportable and sink_delta (#25994)
  • Release musl builds (#25894)
  • Implement streaming decompression for CSV COUNT(*) fast path (#25988)
  • Add nulls support for rolling_mean_by (#25917)
  • Add lazy collect_all (#25991)
  • Add streaming decompression for NDJSON schema inference (#25992)
  • Improved handling of unqualified SQL JOIN columns that are ambiguous (#25761)
  • Drop Python 3.9 support (#25984)
  • Expose record batch size in {sink,write}_ipc (#25958)
  • Add null_on_oob parameter to expr.get (#25957)
  • Suggest correct timezone if timezone validation fails (#25937)
  • Support streaming IPC scan from S3 object store (#25868)
  • Implement streaming CSV schema inference (#25911)
  • Support hashing of meta expressions (#25916)
  • Improve SQLContext recognition of possible table objects in the Python globals (#25749)
  • Add pl.Expr.(min|max)_by (#25905)
  • Improve MemSlice Debug impl (#25913)
  • Implement or fix json encode/decode for (U)Int128, Categorical, Enum, Decimal (#25896)
  • Expand scatter to more dtypes (#25874)
  • Implement streaming CSV decompression (#25842)
  • Add Series sql method for API consistency (#25792)
  • Mark Polars as safe for free-threading (#25677)
  • Support Binary and Decimal in arg_(min|max) (#25839)
  • Allow Decimal parsing in str.json_decode (#25797)
  • Add shift support for Object data type (#25769)
  • Add missing Series.arr.mean (#25774)
  • Allow scientific notation when parsing Decimals (#25711)
🐞 Bug fixes
  • Release GIL on collect_batches (#26033)
  • Missing buffer update in String is_in Parquet pushdown (#26019)
  • Make struct.with_fields data model coherent (#25610)
  • Incorrect output order for order sensitive operations after join_asof (#25990)
  • Use SeriesExport for pyo3-polars FFI (#26000)
  • Add pl.Schema to type signature for DataFrame.cast (#25983)
  • Don't write Parquet min/max statistics for i128 (#25986)
  • Ensure chunk consistency in in-memory join (#25979)
  • Fix varying block metadata length in IPC reader (#25975)
  • Implement collect_batches properly in Rust (#25918)
  • Fix panic on arithmetic with bools in list (#25898)
  • Convert to index type with strict cast in some places (#25912)
  • Empty dataframe in streaming non-strict hconcat (#25903)
  • Infer large u64 in json as i128 (#25904)
  • Set http client timeouts to 10 minutes (#25902)
  • Correct lexicographic ordering for Parquet BYTE_ARRAY statistics (#25886)
  • Raise error on duplicate group_by names in upsample() (#25811)
  • Correctly export view buffer sizes nested in Extension types (#25853)
  • Fix DataFrame.estimated_size not handling overlapping chunks correctly (#25775)
  • Ensure Kahan sum does not introduce NaN from infinities (#25850)
  • Trim excess bytes in parquet decode (#25829)
  • Fix panic/deadlock sinking parquet with rows larger than 64MB estimated size (#25836)
  • Fix quantile midpoint interpolation (#25824)
  • Don't use cast when converting from physical in list.get (#25831)
  • Invalid null count on int -> categorical cast (#25816)
  • Update groups in list.eval (#25826)
  • Use downcast before FFI conversion in PythonScan (#25815)
  • Double-counting of row metrics (#25810)
  • Cast nulls to expected type in streaming union node (#25802)
  • Incorrect slice pushdown into map_groups (#25809)
  • Fix panic writing parquet with single bool column (#25807)
  • Fix upsample with group_by incorrectly introduced NULLs on group key columns (#25794)
  • Panic in top_k pruning (#25798)
  • Fix incorrect collect_schema for unpivot followed by join (#25782)
  • Verify arr namespace is called from array column (#25650)
  • Ensure LazyFrame.serialize() unchanged after collect_schema() (#25780)
  • Function map_(rows|elements) with return_dtype = pl.Object (#25753)
  • Fix incorrect cargo sub-feature (#25738)
📖 Documentation
  • Fix display of deprecation warning (#26010)
  • Document null behaviour for rank (#25887)
  • Add QUALIFY clause and SUBSTRING function to the SQL docs (#25779)
  • Update mixed-offset datetime parsing example in user guide (#25915)
  • Update bare-metal docs for mounted anonymous results (#25801)
  • Fix credential parameter name in cloud-storage.py (#25788)
  • Configuration options update (#25756)
🛠️ Other improvements
  • Update rust compiler (#26017)
  • Improve csv test coverage (#25980)
  • Ramp up CSV read size (#25997)
  • Mark lazy parameter to collect_all as unstable (#25999)
  • Update ruff action and simplify version handling (#25940)
  • Run python lint target as part of pre-commit (#25982)
  • Disable HTTP timeout for receiving response body (#25970)
  • Fix mypy lint (#25963)
  • Add AI contribution policy (#25956)
  • Fix failing scan delta S3 test (#25932)
  • Improve MemSlice Debug impl (#25913)
  • Remove and deprecate batched csv reader (#25884)
  • Remove unused AnonymousScan functions (#25872)
  • Filter DeprecationWarning from pyparsing indirectly through pyiceberg (#25854)
  • Various small improvements (#25835)
  • Clear venv with appropriate version of Python (#25851)
  • Skip schema inference if schema provided for scan_csv/ndjson (#25757)
  • Ensure proper async connection cleanup on DB test exit (#25766)
  • Ensure we uninstall other Polars runtimes in CI (#25739)
  • Make 'make requirements' more robust (#25693)
  • Remove duplicate compression level types (#25723)

Thank you to all our contributors for making this release possible! @AndreaBozzo, @EndPositive, @Kevin-Patyk, @MarcoGorelli, @Voultapher, @alexander-beedie, @anosrepenilno, @arlyon, @azimafroozeh, @carnarez, @dependabot[bot], @dsprenkels, @edizeqiri, @eitanf, @gab23r, @henryharbeck, @hutch3232, @ion-elgreco, @jqnatividad, @kdn36, @lun3x, @m1guelperez, @mcrumiller, @nameexhaustion, @orlp, @ritchie46, @sachinn854, @yonikremer and dependabot[bot]

View originalPermalink
How 1.37.0 went
1.36.1

Python Polars 1.36.1

Added 1
  • Allow creation of Object literal
Changed 3
  • Tune partitioned sink_parquet cloud performance
  • Don't collect schema in SQL union processing
  • Upgrade to latest version of sqlparser-rs
Fixed 6
  • Don't invalidate node in cluster-with-columns
  • Add missing type stubs for bin_slice, bin_head, and bin_tail
  • Binary slice methods missing from Series and docs
  • Mix-up of variable_name/value_name in unpivot
  • Invalid usage of drop_first in to_dummies when nulls present
  • Update slab to version without RUSTSEC
🚀 Performance improvements
  • Tune partitioned sink_parquet cloud performance (#25687)
✨ Enhancements
  • Allow creation of Object literal (#25690)
  • Don't collect schema in SQL union processing (#25675)
🐞 Bug fixes
  • Don't invalidate node in cluster-with-columns (#25714)
  • Move boto3 extra from s3fs in dev requirements (#25667)
  • Add missing type stubs for bin_slice, bin_head, and bin_tail (#25697)
  • Binary slice methods missing from Series and docs (#25683)
  • Mix-up of variable_name/value_name in unpivot (#25685)
  • Invalid usage of drop_first in to_dummies when nulls present (#25435)
📖 Documentation
  • Fix typos in Excel and Pandas migration guides (#25709)
  • Add "right" to how options in join() docstrings (#25678)
🛠️ Other improvements
  • Move Object lit fix earlier in the function (#25713)
  • Remove unused decimal file (#25701)
  • Move boto3 extra from s3fs in dev requirements (#25667)
  • Upgrade to latest version of sqlparser-rs (#25673)
  • Update slab to version without RUSTSEC (#25686)
  • Fix typo (#25684)

Thank you to all our contributors for making this release possible! @AndreaBozzo, @Kevin-Patyk, @alexander-beedie, @dsprenkels, @jamesfricker, @mcrumiller, @nameexhaustion, @orlp and @ritchie46

View originalPermalink
How 1.36.1 went
1.36.0

Python Polars 1.36.0

Added 24
  • Add Extension types
  • Add SQL support for the QUALIFY clause
  • Add bin.slice(), bin.head(), and bin.tail() methods
  • Add SQL syntax support for CROSS JOIN UNNEST(col)
  • Add separate env var to log tracked metrics
  • Expose fields for generating physical plan visualization data
Changed 20
  • Allow pl.Object in pivot value
  • Temporal quantile in rolling context
  • Allow elementwise Expr.over in aggregation context
  • Automatically Parquet dictionary encode floats
  • Support unique_counts for all datatypes
  • Allow hash for all List dtypes
Fixed 12
  • Fix streaming SchemaMismatch panic on list.drop_nulls
  • Fix panic on Boolean rolling_sum calculation for list or array eval
  • Fix panic edge-case when scanning hive partitioned data
  • Fix empty format handling
  • Improve SQL GROUP BY and ORDER BY expression resolution, handling aliasing edge-cases
  • Preserve List inner dtype during chunked take operations

🏆 Highlights

  • Add Extension types (#25322)
✨ Enhancements
  • Add SQL support for the QUALIFY clause (#25652)
  • Add bin.slice(), bin.head(), and bin.tail() methods (#25647)
  • Add SQL syntax support for CROSS JOIN UNNEST(col) (#25623)
  • Add separate env var to log tracked metrics (#25586)
  • Expose fields for generating physical plan visualization data (#25562)
  • Allow pl.Object in pivot value (#25533)
  • Minor improvement for as_struct repr (#25529)
  • Temporal quantile in rolling context (#25479)
  • Add quantile for missing temporals (#25464)
  • Add strict parameter to pl.concat(how='horizontal') (#25452)
  • Support decimals in search_sorted (#25450)
  • Expose and document pl.Categories (#25443)
  • Use reference to Graph pipes when flushing metrics (#25442)
  • Extend SQL UNNEST support to handle multiple array expressions (#25418)
  • Add SQL support for ROW_NUMBER, RANK, and DENSE_RANK functions (#25409)
  • Allow elementwise Expr.over in aggregation context (#25402)
  • Add SQL support for named WINDOW references (#25400)
  • Add leftmost option to str.replace_many / str.find_many / str.extract_many (#25398)
  • Automatically Parquet dictionary encode floats (#25387)
  • Support unique_counts for all datatypes (#25379)
  • Add maintain_order to Expr.mode (#25377)
  • Allow hash for all List dtypes (#25372)
  • Add empty_as_null and keep_nulls to {Lazy,Data}Frame.explode (#25369)
  • Display function of streaming physical plan map node (#25368)
  • Allow slice on scalar in aggregation context (#25358)
  • Allow implode and aggregation in aggregation context (#25357)
  • Move GraphMetrics into StreamingQuery (#25310)
  • Documentation on Polars Cloud manifests (#25295)
  • Add empty_as_null and keep_nulls flags to Expr.explode (#25289)
  • Allow Expr.unique on List/Array with non-numeric types (#25285)
  • Raise suitable error on non-integer "n" value for clear (#25266)
  • Allow Expr.rolling in aggregation contexts (#25258)
  • Allow bare .row() on a single-row DataFrame, equivalent to .item() on a single-element DataFrame (#25229)
  • Support additional forms of SQL CREATE TABLE statements (#25191)
  • Add support for Float16 dtype (#25185)
  • Support column-positional SQL "UNION" operations (#25183)
  • Add unstable Schema.to_arrow() (#25149)
  • Make DSL-hash skippable (#25140)
  • Improve error message on unsupported SQL subquery comparisons (#25135)
  • Support arbitrary expressions in SQL JOIN constraints (#25132)
  • Allow arbitrary expressions as the Expr.rolling index_column (#25117)
  • Set polars/ user-agent (#25112)
  • Support ewm_var/std in streaming engine (#25109)
  • Rewrite IR::Scan to IR::DataFrameScan in expand_datasets when applicable (#25106)
  • Add ignore_nulls to first / last (#25105)
  • Allow arbitrary Expressions in "subset" parameter of unique frame method (#25099)
  • Add BIT_NOT support to the SQL interface (#25094)
  • Streaming {Expr,LazyFrame}.rolling (#25058)
  • Add LazyFrame.pivot (#25016)
  • Add SQL support for LEAD and LAG functions (#23956)
  • Add having to group_by context (#23550)
  • Add show methods for DataFrame and LazyFrame (#19634)
🚀 Performance improvements
  • Set parallelization threshold in take_unchecked_impl (#25672)
  • New single file IO sink pipeline enabled for sink_parquet (#25670)
  • Correct overly eager local predicate insertion for unpivot (#25644)
  • New partitioned IO sink pipeline enabled for sink_parquet (#25629)
  • Use strong hash instead of traversal for CSPE equality (#25537)
  • Reduce HuggingFace API calls (#25521)
  • Fix panic in is_between support in streaming Parquet predicate push down (#25476)
  • Faster kernels for rle_lengths (#25448)
  • Mark output of more non-order-maintaining ops as unordered (#25419)
  • Enable predicate expressions on unsigned integers (#25416)
  • Allow detecting plan sortedness in more cases (#25408)
  • Add parquet prefiltering for string regexes (#25381)
  • Fast find start window in group_by_dynamic with large offset (#25376)
  • Use fast path for agg_min/agg_max when nulls present (#25374)
  • Add streaming native LazyFrame.group_by_dynamic (#25342)
  • Fuse positive slice into streaming LazyFrame.rolling (#25338)
  • Mark Expr.reshape((-1,)) as row separable (#25326)
  • Return references from aexpr_to_leaf_names_iter (#25319)
  • Use bitmap instead of Vec in first/last w. skip_nulls (#25318)
  • Lazy gather for {forward,backward}_fill in group-by contexts (#25115)
  • Add streaming sorted Group-By (#25013)
🐞 Bug fixes
  • Rechunk on nested dtypes in take_unchecked_impl parallel path (#25662)
  • Fix streaming SchemaMismatch panic on list.drop_nulls (#25661)
  • Fix panic on Boolean rolling_sum calculation for list or array eval (#25660)
  • Fix "dtype is unknown" panic in cross joins with literals (#25658)
  • Fix panic edge-case when scanning hive partitioned data (#25656)
  • Fix "unreachable code" panic in UDF dtype inference (#25655)
  • Address potential "batch_size" parameter collision in scan_pyarrow_dataset (#25654)
  • Fix empty format handling (#25638)
  • Improve SQL GROUP BY and ORDER BY expression resolution, handling aliasing edge-cases (#25637)
  • Preserve List inner dtype during chunked take operations (#25634)
  • Fix lifetime for AmortSeries lazy group iterator (#25620)
  • Fix spearman panicking on nulls (#25619)
  • Properly resolve HAVING clause during SQL GROUP BY operations (#25615)
  • Prevent false positives in is_in for large integers (#25608)
  • Differentiate between empty list an no list for unpivot (#25597)
  • Bug in boolean unique_counts (#25587)
  • Hang in multi-chunk DataFrame .rows() (#25582)
  • Correct arr_to_any_value for object arrays (#25581)
  • Have PySeries::new_f16 receive pf16s instead of f32s (#25579)
  • Set Float16 parquet schema type to Float16 (#25578)
  • Fix incorrect .list.eval after slicing operations (#25540)
  • Strict conversion AnyValue to Struct (#25536)
  • Rolling mean/median for temporals (#25512)
  • Add .rolling_rank() support for temporal types and pl.Boolean (#25509)
  • Fix occurence of exact matches of .join_asof(strategy="nearest", allow_exact_matches=False, ...) (#25506)
  • Always respect return_dtype in map_elements and map_rows (#25504)
  • Fix group lengths check in sort_by with AggregatedScalar (#25503)
  • Fix dictionary replacement error in write_ipc() (#25497)
  • Fix expr slice pushdown causing shape error on literals (#25485)
  • Allow empty list in sort_by in list.eval context (#25481)
  • Raise error on out-of-range dates in temporal operations (#25471)
  • Validate list.slice parameters are not lists (#25458)
  • Make sum on strings error in group_by context (#25456)
  • Prevent panic when joining sorted LazyFrame with itself (#25453)
  • Apply CSV dict overrides by name only (#25436)
  • Incorrect result in aggregated first/last with ignore_nulls (#25414)
  • Fix off-by-one bug in ColumnPredicates generation for inequalities operating on integer columns (#25412)
  • Use Cargo.template.toml to prevent git dependencies from using template (#25392)
  • Fix arr.{eval,agg} in aggregation context (#25390)
  • Support AggregatedList in list.{eval,agg} context (#25385)
  • Nested dtypes in streaming first_non_null/last_non_null (#25375)
  • Remove Expr casts in pl.lit invocations (#25373)
  • Optimize projection pushdown through HConcat (#25371)
  • Revert pl.format behavior with nulls (#25370)
  • Correct eq_missing for struct with nulls (#25363)
  • Resolve edge-case with SQL aggregates that have the same name as one of the GROUP BY keys (#25362)
  • Unique on literal in aggregation context (#25359)
  • Aggregation with drop_nulls on literal (#25356)
  • SQL NATURAL joins should coalesce the key columns (#25353)
  • Mark {forward,backward}_fill as length_preserving (#25352)
  • Correct drop_items for scalar input (#25351)
  • Schema mismatch with list.agg, unique and scalar (#25348)
  • AnyValue::to_physical for categoricals (#25341)
  • Bugs in pl.from_repr with signed exponential floats and line wrapping (#25331)
  • Remove ClosableFile (#25330)
  • Increase precision when constructing float Series (#25323)
  • Fix link errors reported by markdown-link-check (#25314)
  • Parquet is_in for mixed validity pages (#25313)
  • Fix building polars-plan with features lazy,concat_str (but no strings) (#25306)
  • Fix building polars-mem-engine with the async feature (#25300)
  • Nested dtypes in streaming first/last (#25298)
  • Fix length preserving check for eval expressions in streaming engine (#25294)
  • Panic exception when calling Expr.rolling in .over (#25283)
  • Don't quietly allow unsupported SQL SELECT clauses (#25282)
  • Reverse on chunked struct (#25281)
  • Correct {first,last}_non_null if there are empty chunks (#25279)
  • Incorrect results for aggregated {n_,}unique on bools (#25275)
  • Run async DB queries with regular asyncio if not inside a running loop (#25268)
  • Fix small bug with PyExpr to PyObject conversion (#25265)
  • Fix building polars-expr without timezones feature (#25254)
  • Correctly prune projected columns in hints (#25250)
  • Address multiple issues with SQL OVER clause behaviour for window functions (#25249)
  • Allow Null dtype values in scatter (#25245)
  • Make str.json_decode output deterministic with lists (#25240)
  • Correct handle requested stops in streaming shift (#25239)
  • Use (i64, u64) for VisualizationData (offset, length) slices (#25203)
  • Fix serialization of lazyframes containing huge tables (#25190)
  • Fix single-column CSV header duplication with leading empty lines (#25186)
  • Enhanced column resolution/tracking through multi-way SQL joins (#25181)
  • Fix format_str in case of multiple chunks (#25162)
  • Handle some unusual pl.col.<colname> edge-cases (#25153)
  • Fix incorrect reshape on sliced lists (#25139)
  • Support "index" as column name in group_by iterator (#25138)
  • Fix panic in dt.truncate for invalid duration strings (#25124)
  • DSL_SCHEMA_HASH should not changed by line endings (#25123)
  • Don't trigger DeprecationWarning from SQL "IN" constraints that use subqueries (#25111)
  • Solve multiple issues relating to arena mutation in SQL subqueries (#25110)
  • Return the correct string-case Expr reprs (#25101)
  • Fix groups update on slices with different offsets (#25097)
  • Unique key names in streaming sort/top_k (#25082)
  • Fix CSV select(len()) off by 1 with comment prefix (#25069)
  • Raise error for all/any on list instead of panic (#25018)
  • Ensure out-of-range integers and other edge case values don't give wrong results for index_of() (#24369)
  • Improve SQL UNNEST behaviour (#22546)
📖 Documentation
  • Document schema parameter in meta methods (#25543)
  • Correct link to datetime_range instead of date_range in resampling page (#25532)
  • Remove lzo from parquet write options (#25522)
  • Deprecate Categorical functions for lexical ordering and local checks (#25514)
  • Update LazyFrame.collect_schema() docstring (#25508)
  • Update on-premise documentation (#25489)
  • Add LazyFrame.pivot to reference guide (#25482)
  • Fix incorrect 'bitwise' in any_horizontal/all_horizontal docstring (#25469)
  • Add docstring example showing str.slice taking Expression params (#25461)
  • Add Extension and BaseExtension to doc index (#25444)
  • Add polars-on-premise documentation (#25431)
  • Add having API references (#25428)
  • Explain aggregation & sorting of lists (#25260)
  • Fix LanceDB URL (#25198)
  • Update user guide for QueryProgress rename to QueryProfile (#25195)
  • Update LazyFrame.remote signature (#25175)
  • Fix source path (#25170)
  • Fix non-existent replace_all reference in replace docs (#25161)
  • Mention Narwhals in ecosystem page (#25100)
  • Clarify bitwise behaviour of and_, or_, and not_ Expressions on integer columns (#25092)
🧪 Tests
  • Add reliable test for pl.format on multiple chunks (#25164)
🔧 CI
  • Avoid relabelling changes-dsl on every commit (#25216)
  • Automatically label pull requests that change the DSL (#25177)
🏗️ Build system
  • Fix make fmt and make lint commands (#25200)
  • Make building the docs on macOS more reliable (#25095)
🛠️ Other improvements
  • Add "panic" and "streaming" tagging to issue-labeler workflow (#25657)
  • Use dtype for group_aware evaluation on ApplyExpr (#25639)
  • Ensure literal-only SELECT broadcast conforms to SQL semantics (#25633)
  • Ensure we hash all attributes and visit all children in traverse_and_hash_aexpr (#25627)
  • Rename polars-on-premise to polars-on-premises (#25617)
  • Constrain new issue-labeler workflow to the Issue title (#25614)
  • Avoid rechunk requirement for Series.iter() (#25603)
  • Help categorise Issues by automatically applying labels (using the same patterns used for labelling PRs) (#25599)
  • Add disk-cleaning step for Ubuntu runners (#25593)
  • Show on streaming engine (#25589)
  • Ignore a couple of unexplained typing errors (#25580)
  • Skip existing files in pypi upload (#25576)
  • Fix template path in release-python workflow (#25565)
  • Add asserts and tests for list.eval on multiple chunks with slicing (#25559)
  • Skip rust integration tests for coverage in CI (#25558)
  • Add Final type-qualifier to module-level constants (#25556)
  • Print expected DSL schema hashes if mismatched (#25526)
  • Update partitioned sink IR (#25524)
  • Fix --uv argument for benchmark-remote (#25513)
  • Add proptest AnyValue strategies (#25510)
  • Fix rolling kernel dispatch with monotonic group attribute (#25494)
  • Fix feature gating TZ_AWARE_RE again (#25493)
  • Run maturin with --uv option (#25490)
  • Add proptest DataFrame strategy (#25446)
  • Add some cleanup (#25445)
  • Add assert_sql_matches coverage for SQL DISTINCT and DISTINCT ON syntax (#25440)
  • Test for group_by(...).having(...) (#25430)
  • Remove aggregation context Context (#25424)
  • Remove debug file write from test suite (#25393)
  • Remove unused import (#25365)
  • Enable more streaming tests (#25364)
  • Dispatch Series.set to zip_with_same_dtype (#25327)
  • Remove Column::Partitioned (#25324)
  • Add toolchain file to runtimes for sdist (#25311)
  • Fix typo in CI release workflow (#25309)
  • Refactor sink IR (#25308)
  • Directly take CloudScheme in parse_cloud_options() (#25304)
  • Remove PyPartitioning (#25303)
  • Simplify sink parameter passing from Python (#25302)
  • Better coverage for group_by aggregations (#25290)
  • Use dedicated runtime packages from template (#25284)
  • Add test for unique with column subset (#25241)
  • Fix Decimal precision annotation (#25227)
  • Refactor dt_range functions (#25225)
  • Add proptest strategies for Series nested types (#25220)
  • Update markdown link checker (#25201)
  • Add ElementExpr for _eval expressions (#25199)
  • Upgraded ruff and typos and made the necessary lint updates (#25196)
  • Make python docs build again (#25165)
  • Upgrade to schemars 0.9.0 (#25158)
  • Update versions (#25141)
  • Silence unused mut warning (#25093)
  • Add proptest strategies for Series logical types (#24849)
♻️ Refactoring
  • Make polars-plan constants more consistent (#25645)
  • Add support for multi-column reductions (#25640)
  • Simplify _write_any_value (#25622)
  • Add parquet file write pipeline for new IO sinks (#25618)
  • Add streaming IO sink components (#25594)
  • Add arg_sort() and Writeable::as_buffered() (#25583)
  • Take task priority argument in parallelize_first_to_local (#25563)
  • Rename URL_ENCODE_CHARSET to HIVE_ENCODE_CHARSET (#25554)
  • Remove verbose prints on file opens (#25523)
  • Remove some dead argminmax impl code (#25501)
  • Take sync parameter in Writeable::close() (#25475)
  • Fix unsoundness in ChunkedArray::{first, last} (#25449)
  • Take &dyn Any instead of Box<dyn Any> in python object converters (#25421)
  • Accept multiple files in pipe_with_schema (#25388)
  • Add oneshot channel to polars-stream (#25378)
  • Remove incorrect cast in reduce code (#25321)
  • Clean up CSPE callsite (#25215)
  • Move ewm variance code to polars-compute (#25188)
  • Make pipe_with_schema work on Arced schema (#25155)
  • Remove lower_ir conversion from Scan to InMemorySource (#25150)
  • Add functions for scan_lines (#25136)
  • Remove unused optimization_toggle (#25130)
  • Support for named/anonymous aggregations (#25118)
  • Remove old join projection pushdown logic (#25088)
  • Remove unused row-count (#25080)
  • Add IR for scan_lines (#25066)
  • Add stateful EwmCov kernel (#25065)
  • Move EwmMeanState to polars-compute (#25034)
  • Move asof tolerance type coercion to IR conversion (#25033)
  • Move supertype determination and casting to IR for date_range and related functions (#24084)

Thank you to all our contributors for making this release possible! @AndreaBozzo, @DannyStoll1, @EndPositive, @JakubValtar, @Jesse-Bakker, @Kevin-Patyk, @MarcoGorelli, @TNieuwdorp, @Voultapher, @alexander-beedie, @borchero, @c-peters, @cBournhonesque, @camriddell, @carnarez, @cmdlineluser, @coastalwhite, @cr7pt0gr4ph7, @davanstrien, @davidia, @dsprenkels, @etiennebacher, @feliblo, @guilhem-dvr, @itamarst, @jannickj, @jetuk, @kdn36, @lun3x, @marinegor, @mcrumiller, @nameexhaustion, @orlp, @pomo-mondreganto, @ritchie46, @vyasr, @wtn, and more!

View originalPermalink
How 1.36.0 went
1.36.0-beta.2Pre-release

Python Polars 1.36.0-beta.2

Added 16
  • Add Extension types
  • Add SQL support for ROW_NUMBER, RANK, and DENSE_RANK functions
  • Add SQL support for named WINDOW references
  • Add BIT_NOT support to the SQL interface
  • Add LazyFrame.pivot
  • Add allow_empty flag to item
Changed 4
  • Allow Expr.rolling in aggregation contexts
  • Allow Expr.unique on List/Array with non-numeric types
  • Allow glimpse to return a DataFrame
  • Allow hash for all List dtypes
🏆 Highlights
  • Add Extension types (#25322)
✨ Enhancements
  • Add SQL support for ROW_NUMBER, RANK, and DENSE_RANK functions (#25409)
  • Add SQL support for named WINDOW references (#25400)
  • Add BIT_NOT support to the SQL interface (#25094)
  • Add LazyFrame.pivot (#25016)
  • Add allow_empty flag to item (#25048)
  • Add empty_as_null and keep_nulls flags to Expr.explode (#25289)
  • Add empty_as_null and keep_nulls to {Lazy,Data}Frame.explode (#25369)
  • Add having to group_by context (#23550)
  • Add ignore_nulls to first / last (#25105)
  • Add maintain_order to Expr.mode (#25377)
  • Add quantile for missing temporals (#25464)
  • Add leftmost option to str.replace_many / str.find_many / str.extract_many (#25398)
  • Add strict parameter to pl.concat(how='horizontal') (#25452)
  • Add support for Float16 dtype (#25185)
  • Add unstable Schema.to_arrow (#25149)
  • Allow Expr.rolling in aggregation contexts (#25258)
  • Allow Expr.unique on List/Array with non-numeric types (#25285)
  • Allow glimpse to return a DataFrame (#24803)
  • Allow hash for all List dtypes (#25372)
  • Allow implode and aggregation in aggregation context (#25357)
  • Allow slice on scalar in aggregation context (#25358)
  • Allow arbitrary Expressions in "subset" parameter of unique frame method (#25099)
  • Allow arbitrary expressions as the Expr.rolling index_column (#25117)
  • Allow bare .row on a single-row DataFrame, equivalent to .item on a single-element DataFrame (#25229)
  • Allow elementwise Expr.over in aggregation context (#25402)
  • Allow pl.Object in pivot value (#25533)
  • Automatically Parquet dictionary encode floats (#25387)
  • Display function of streaming physical plan map node (#25368)
  • Documentation on Polars Cloud manifests (#25295)
  • Expose and document pl.Categories (#25443)
  • Expose fields for generating physical plan visualization data (#25562)
  • Extend SQL UNNEST support to handle multiple array expressions (#25418)
  • Improve SQL UNNEST behaviour (#22546)
  • Improve error message on unsupported SQL subquery comparisons (#25135)
  • Make DSL-hash skippable (#25140)
  • Minor improvement for as_struct repr (#25529)
  • Move GraphMetrics into StreamingQuery (#25310)
  • Raise suitable error on non-integer "n" value for clear (#25266)
  • Rewrite IR::Scan to IR::DataFrameScan in expand_datasets when applicable (#25106)
  • Set polars/ user-agent (#25112)
  • Streaming {Expr,LazyFrame}.rolling (#25058)
  • Support BYTE_ARRAY backed Decimals in Parquet (#25076)
  • Support ewm_var/std in streaming engine (#25109)
  • Support unique_counts for all datatypes (#25379)
  • Support additional forms of SQL "CREATE TABLE" statements (#25191)
  • Support arbitrary expressions in SQL JOIN constraints (#25132)
  • Support column-positional SQL "UNION" operations (#25183)
  • Support decimals in search_sorted (#25450)
  • Temporal quantile in rolling context (#25479)
  • Use reference to Graph pipes when flushing metrics (#25442)
🚀 Performance improvements
  • Add parquet prefiltering for string regexes (#25381)
  • Add streaming native LazyFrame.group_by_dynamic (#25342)
  • Add streaming sorted Group-By (#25013)
  • Allow detecting plan sortedness in more cases (#25408)
  • Don't recompute full rolling moment window when NaNs/nulls leave the window (#25078)
  • Enable predicate expressions on unsigned integers (#25416)
  • Fast find start window in group_by_dynamic with large offset (#25376)
  • Faster kernels for rle_lengths (#25448)
  • Fuse positive slice into streaming LazyFrame.rolling (#25338)
  • Lazy gather for {forward,backward}_fill in group-by contexts (#25115)
  • Mark Expr.reshape((-1,)) as row separable (#25326)
  • Mark output of more non-order-maintaining ops as unordered (#25419)
  • Optimize ipc stream read performance (#24671)
  • Reduce HuggingFace API calls (#25521)
  • Return references from aexpr_to_leaf_names_iter (#25319)
  • Skip filtering scan IR if no paths were filtered (#25037)
  • Use bitmap instead of Vec in first/last w. skip_nulls (#25318)
  • Use fast path for agg_min/agg_max when nulls present (#25374)
  • Use strong hash instead of traversal for CSPE equality (#25537)
🐞 Bug fixes
  • Add .rolling_rank support for temporal types and pl.Boolean (#25509)
  • Address issues with SQL OVER clause behaviour for window functions (#25249)
  • Aggregation with drop_nulls on literal (#25356)
  • Allow Null dtype values in scatter (#25245)
  • Allow broadcast in group_by for ApplyExpr and BinaryExpr (#25053)
  • Allow empty list in sort_by in list.eval context (#25481)
  • Allow for negative time in group_by_dynamic iterator (#25041)
  • Always respect return_dtype in map_elements and map_rows (#25504)
  • AnyValue::to_physical for categoricals (#25341)
  • Apply CSV dict overrides by name only (#25436)
  • Block predicate pushdown when group_by key values are changed (#25032)
  • Bugs in pl.from_repr with signed exponential floats and line wrapping (#25331)
  • Correct drop_items for scalar input (#25351)
  • Correct eq_missing for struct with nulls (#25363)
  • Correct {first,last}_non_null if there are empty chunks (#25279)
  • Correct handle requested stops in streaming shift (#25239)
  • Correctly prune projected columns in hints (#25250)
  • DSL_SCHEMA_HASH should not changed by line endings (#25123)
  • Don't push down predicates passed inserted cache nodes (#25042)
  • Don't quietly allow unsupported SQL SELECT clauses (#25282)
  • Don't trigger DeprecationWarning from SQL "IN" constraints that use subqueries (#25111)
  • Enhanced column resolution/tracking through multi-way SQL joins (#25181)
  • Ensure SQL table alias resolution checks against CTE aliases on fallback (#25071)
  • Ensure out-of-range integers and other edge case values don't give wrong results for index_of (#24369)
  • Fix CSV select(len) off by 1 with comment prefix (#25069)
  • Fix arr.{eval,agg} in aggregation context (#25390)
  • Fix format_str in case of multiple chunks (#25162)
  • Fix groups update on slices with different offsets (#25097)
  • Fix assertion panic on group_by (#25179)
  • Fix building polars-expr without timezones feature (#25254)
  • Fix building polars-mem-engine with the async feature (#25300)
  • Fix building polars-plan with features lazy,concat_str (but no strings) (#25306)
  • Fix dictionary replacement error in write_ipc (#25497)
  • Fix expr slice pushdown causing shape error on literals (#25485)
  • Fix field metadata for nested categorical PyCapsule export (#25052)
  • Fix group lengths check in sort_by with AggregatedScalar (#25503)
  • Fix handling Null dtype in ApplyExpr on group_by (#25077)
  • Fix incorrect .list.eval after slicing operations (#25540)
  • Fix incorrect reshape on sliced lists (#25139)
  • Fix length preserving check for eval expressions in streaming engine (#25294)
  • Fix occurence of exact matches of .join_asof(strategy="nearest", allow_exact_matches=False, ...) (#25506)
  • Fix off-by-one bug in ColumnPredicates generation for inequalities operating on integer columns (#25412)
  • Fix panic if scan predicate produces 0 length mask (#25089)
  • Fix panic in dt.truncate for invalid duration strings (#25124)
  • Fix panic in is_between support in streaming Parquet predicate push down (#25476)
  • Fix panic when using struct field as join key (#25059)
  • Fix serialization of lazyframes containing huge tables (#25190)
  • Fix single-column CSV header duplication with leading empty lines (#25186)
  • Fix small bug with PyExpr to PyObject conversion (#25265)
  • Group-By aggregation problems caused by AmortSeries (#25043)
  • Handle some unusual pl.col.<colname> edge-cases (#25153)
  • Incorrect result in aggregated first/last with ignore_nulls (#25414)
  • Incorrect results for aggregated {n_,}unique on bools (#25275)
  • Invert drop_nans filtering in group-by context (#25146)
  • Make str.json_decode output deterministic with lists (#25240)
  • Mark {forward,backward}_fill as length_preserving (#25352)
  • Minor improvement to internal is_pycapsule utility function (#25073)
  • Nested dtypes in streaming first_non_null/last_non_null (#25375)
  • Nested dtypes in streaming first/last (#25298)
  • Panic exception when calling Expr.rolling in .over (#25283)
  • Panic in group_by_dynamic with group_by and multiple chunks (#25075)
  • Parquet is_in for mixed validity pages (#25313)
  • Prevent panic when joining sorted LazyFrame with itself (#25453)
  • Raise error for all/any on list instead of panic (#25018)
  • Raise error on out-of-range dates in temporal operations (#25471)
  • Remove Expr casts in pl.lit invocations (#25373)
  • Resolve edge-case with SQL aggregates that have the same name as one of the "GROUP BY" keys (#25362)
  • Return the correct string-case Expr reprs (#25101)
  • Reverse on chunked struct (#25281)
  • Revert pl.format behavior with nulls (#25370)
  • Rolling mean/median for temporals (#25512)
  • Run async DB queries with regular asyncio if not inside a running loop (#25268)
  • SQL "NATURAL" joins should coalesce the key columns (#25353)
  • Schema mismatch with list.agg, unique and scalar (#25348)
  • Solve multiple issues relating to arena mutation in SQL subqueries (#25110)
  • Strict conversion AnyValue to Struct (#25536)
  • Support "index" as column name in group_by iterator (#25138)
  • Support AggregatedList in list.{eval,agg} context (#25385)
  • The SQL interface should use logical, not bitwise, behaviour for unary "NOT" operator (#25091)
  • Unique key names in streaming sort/top_k (#25082)
  • Unique on literal in aggregation context (#25359)
  • Use (i64, u64) for VisualizationData (offset, length) slices (#25203)
  • Use Cargo.template.toml to prevent git dependencies from using template (#25392)
  • Validate list.slice parameters are not lists (#25458)
  • Wide-table join performance regression (#25222)
📖 Documentation
  • Add Extension and BaseExtension to doc index (#25444)
  • Add LazyFrame.pivot to reference guide (#25482)
  • Add having API references (#25428)
  • Add docstring example showing str.slice taking Expression params (#25461)
  • Add polars-on-premise documentation (#25431)
  • Clarify bitwise behaviour of and_, or_, and not_ Expressions on integer columns (#25092)
  • Correct link to datetime_range instead of date_range in resampling page (#25532)
  • Deprecate Categorical functions for lexical ordering and local checks (#25514)
  • Document schema parameter in meta methods (#25543)
  • Explain aggregation & sorting of lists (#25260)
  • Fix LanceDB URL (#25198)
  • Fix incorrect 'bitwise' in any_horizontal/all_horizontal docstring (#25469)
  • Fix link errors reported by markdown-link-check (#25314)
  • Fix non-existent replace_all reference in replace docs (#25161)
  • Fix source path (#25170)
  • Fix typo in public dataset URL (#25044)
  • Mention Narwhals in ecosystem page (#25100)
  • Remove lzo from parquet write options (#25522)
  • Update LazyFrame.collect_schema docstring (#25508)
  • Update LazyFrame.remote signature (#25175)
  • Update on-premise documentation (#25489)
  • Update user guide for QueryProgress rename to QueryProfile (#25195)
🧪 Tests
  • Add assert_sql_matches coverage for SQL "DISTINCT" and "DISTINCT ON" syntax (#25440)
  • Add reliable test for pl.format on multiple chunks (#25164)
  • Add test for unique with column subset (#25241)
  • Better coverage for group_by aggregations (#25290)
  • Test for group_by(...).having(...) (#25430)
🔧 CI
  • Automatically label pull requests that change the DSL (#25177)
  • Avoid relabelling changes-dsl on every commit (#25216)
  • Print expected DSL schema hashes if mismatched (#25526)
  • Skip existing files in pypi upload (#25576)
🏗️ Build system
  • Fix make fmt and make lint commands (#25200)
  • Make building the docs on macOS more reliable (#25095)
🛠️ Other improvements
  • Add Final type-qualifier to module-level constants (#25556)
  • Add proptest AnyValue strategies (#25510)
  • Add proptest DataFrame strategy (#25446)
  • Add proptest strategies for Series logical types (#24849)
  • Add proptest strategies for Series nested types (#25220)
  • Add some cleanup (#25445)
  • Add toolchain file to runtimes for sdist (#25311)
  • Enable more streaming tests (#25364)
  • Fix --uv argument for benchmark-remote (#25513)
  • Fix Decimal precision annotation (#25227)
  • Fix feature gating TZ_AWARE_RE again (#25493)
  • Fix template path in release-python workflow (#25565)
  • Fix typo in CI release workflow (#25309)
  • Make python docs build again (#25165)
  • Remove Column::Partitioned (#25324)
  • Remove debug file write from test suite (#25393)
  • Remove unused import (#25365)
  • Run maturin with --uv option (#25490)
  • Silence unused mut warning (#25093)
  • Skip rust integration tests for coverage in CI (#25558)
  • Update markdown link checker (#25201)
  • Update toolchain (#25007)
  • Update versions (#25141)
  • Upgrade to schemars 0.9.0 (#25158)
  • Upgraded ruff and typos and made the necessary lint updates (#25196)
♻️ Refactoring
  • Accept multiple files in pipe_with_schema (#25388)
  • Add IR for scan_lines (#25066)
  • Add ElementExpr for _eval expressions (#25199)
  • Add asserts and tests for list.eval on multiple chunks with slicing (#25559)
  • Add functions for scan_lines (#25136)
  • Add oneshot channel to polars-stream (#25378)
  • Add stateful EwmCov kernel (#25065)
  • Change group length mismatch error to ShapeError (#25004)
  • Clean up CSPE callsite (#25215)
  • Directly take CloudScheme in parse_cloud_options (#25304)
  • Disable recursive CSPE for now (#25085)
  • Dispatch Series.set to zip_with_same_dtype (#25327)
  • Fix unsoundness in ChunkedArray::{first, last} (#25449)
  • Make pipe_with_schema work on Arced schema (#25155)
  • Move EwmMeanState to polars-compute (#25034)
  • Move asof tolerance type coercion to IR conversion (#25033)
  • Move ewm variance code to polars-compute (#25188)
  • Move supertype determination and casting to IR for date_range and related functions (#24084)
  • Refactor dt_range functions (#25225)
  • Refactor sink IR (#25308)
  • Remove ClosableFile (#25330)
  • Remove PyPartitioning (#25303)
  • Remove aggregation context Context (#25424)
  • Remove incorrect cast in reduce code (#25321)
  • Remove lower_ir conversion from Scan to InMemorySource (#25150)
  • Remove old join projection pushdown logic (#25088)
  • Remove some dead argminmax impl code (#25501)
  • Remove unused optimization_toggle (#25130)
  • Remove unused row-count (#25080)
  • Remove verbose prints on file opens (#25523)
  • Rename URL_ENCODE_CHARSET to HIVE_ENCODE_CHARSET (#25554)
  • Simplify sink parameter passing from Python (#25302)
  • Support for named/anonymous aggregations (#25118)
  • Take &dyn Any instead of Box<dyn Any> in python object converters (#25421)
  • Take sync parameter in Writeable::close (#25475)
  • Update partitioned sink IR (#25524)
  • Use dedicated runtime packages from template (#25284)

Thank you to all our contributors for making this release possible! @AndreaBozzo, @DannyStoll1, @EndPositive, @JakubValtar, @Jesse-Bakker, @Kevin-Patyk, @MarcoGorelli, @TNieuwdorp, @alexander-beedie, @borchero, @c-peters, @cBournhonesque, @carnarez, @cmdlineluser, @coastalwhite, @cr7pt0gr4ph7, @davanstrien, @dsprenkels, @etiennebacher, @feliblo, @itamarst, @jannickj, @jetuk, @kdn36, @lun3x, @marinegor, @mcrumiller, @nameexhaustion, @orlp, @ritchie46, @vyasr, @wtn and more!

View originalPermalink
How 1.36.0-beta.2 went
1.35.2

Python Polars 1.35.2

Fixed 4
  • Fix incorrect drop_nans() result when used in group_by() / over()
  • Fix handling Null dtype in ApplyExpr on group_by
  • Fix assertion panic on group_by
  • Fix wide-table join performance regression

Thank you to all our contributors for making this release possible! @coastalwhite, @kdn36, @nameexhaustion and @ritchie46

View originalPermalink
How 1.35.2 went
1.35.1

Python Polars 1.35.1

Added 2
  • Support BYTE_ARRAY backed Decimals in Parquet
  • Add allow_empty flag to item
Changed 5
  • Don't recompute full rolling moment window when NaNs/nulls leave the window
  • Skip filtering scan IR if no paths were filtered
  • Optimize ipc stream read performance
  • Allow glimpse to return a DataFrame
  • Change group length mismatch error to ShapeError
Fixed 11
  • The SQL interface should use logical, not bitwise, behaviour for unary NOT operator
  • Fix panic if scan predicate produces 0 length mask
  • Ensure SQL table alias resolution checks against CTE aliases on fallback
  • Fix panic in group_by_dynamic with group_by and multiple chunks
  • Fix panic when using struct field as join key
  • Allow broadcast in group_by for ApplyExpr and BinaryExpr
🚀 Performance improvements
  • Don't recompute full rolling moment window when NaNs/nulls leave the window (#25078)
  • Skip filtering scan IR if no paths were filtered (#25037)
  • Optimize ipc stream read performance (#24671)
✨ Enhancements
  • Support BYTE_ARRAY backed Decimals in Parquet (#25076)
  • Allow glimpse to return a DataFrame (#24803)
  • Add allow_empty flag to item (#25048)
🐞 Bug fixes
  • The SQL interface should use logical, not bitwise, behaviour for unary "NOT" operator (#25091)
  • Fix panic if scan predicate produces 0 length mask (#25089)
  • Ensure SQL table alias resolution checks against CTE aliases on fallback (#25071)
  • Panic in group_by_dynamic with group_by and multiple chunks (#25075)
  • Minor improvement to internal is_pycapsule utility function (#25073)
  • Fix panic when using struct field as join key (#25059)
  • Allow broadcast in group_by for ApplyExpr and BinaryExpr (#25053)
  • Fix field metadata for nested categorical PyCapsule export (#25052)
  • Block predicate pushdown when group_by key values are changed (#25032)
  • Group-By aggregation problems caused by AmortSeries (#25043)
  • Don't push down predicates passed inserted cache nodes (#25042)
  • Allow for negative time in group_by_dynamic iterator (#25041)
📖 Documentation
  • Fix typo in public dataset URL (#25044)
🛠️ Other improvements
  • Disable recursive CSPE for now (#25085)
  • Change group length mismatch error to ShapeError (#25004)
  • Update toolchain (#25007)

Thank you to all our contributors for making this release possible! @Kevin-Patyk, @Liyixin95, @alexander-beedie, @coastalwhite, @kdn36, @nameexhaustion, @orlp, @r-brink, @ritchie46 and @stijnherfst

View originalPermalink
How 1.35.1 went
1.35.0

Python Polars 1.35.0

Added 11
  • Add Expr.item to strictly extract a single value from an expression
  • Add list.agg and arr.agg
  • Implement {Expr,Series}.rolling_rank()
  • Add arr.eval
  • Add union() function for unordered concatenation
  • Add name.replace to the set of column rename options
Changed 8
  • Stabilize decimal
  • Support ewm_mean() in streaming engine
  • Allow local scans on polars cloud (configurable)
  • Support MergeSorted in CSPE
  • Make Series init consistent with DataFrame init for string values declared with temporal dtype
  • Improve rolling_(sum|mean) accuracy
  • Allow duration strings with leading "+"
  • Support np.ndarray -> AnyValue conversion
Fixed 1
  • Fix incorrect join_asof on a casted expression
🏆 Highlights
  • Stabilize decimal (#25020)
🚀 Performance improvements
  • Bump foldhash to 0.2.0 and hashbrown to 0.16.0 (#25014)
  • Lower unique to native group-by and speed up n_unique in group-by context (#24976)
  • Better parallelize take{_slice,}_unchecked (#24980)
  • Implement native skew and kurtosis in group-by context (#24961)
  • Use native group-by aggregations for bitwise_* operations (#24935)
  • Address group_by_dynamic slowness in sparse data (#24916)
  • Push filters to PyIceberg (#24910)
  • Native filter/drop_nulls/drop_nans in group-by context (#24897)
  • Implement cumulative_eval using the group-by engine (#24889)
  • Prevent generation of copies of Dataframes in DslPlan serialization (#24852)
  • Implement native null_count, any and all group-by aggregations (#24859)
  • Speed up reverse in group-by context (#24855)
  • Prune unused categorical values when exporting to arrow/parquet/IPC/pickle (#24829)
  • Don't check duplicates on streaming simple projection in release mode (#24830)
  • Lower approx_n_unique to the streaming engine (#24821)
  • Duration/interval string parsing optimisation (2-5x faster) (#24771)
  • Use native reducer for first/last on Decimals, Categoricals and Enums (#24786)
  • Implement indexed method for BitMapIter::nth (#24766)
  • Pushdown slices on plans within unions (#24735)
✨ Enhancements
  • Stabilize decimal (#25020)
  • Support ewm_mean() in streaming engine (#25003)
  • Improve row-count estimates (#24996)
  • Remove filtered scan paths in IR when possible (#24974)
  • Introduce remote Polars MCP server (#24977)
  • Allow local scans on polars cloud (configurable) (#24962)
  • Add Expr.item to strictly extract a single value from an expression (#24888)
  • Add environment variable to roundtrip empty struct in Parquet (#24914)
  • Fast-count for scan_iceberg().select(len()) (#24602)
  • Add glob parameter to scan_ipc (#24898)
  • Prevent generation of copies of Dataframes in DslPlan serialization (#24852)
  • Add list.agg and arr.agg (#24790)
  • Implement {Expr,Series}.rolling_rank() (#24776)
  • Don't require PyArrow for read_database_uri if ADBC engine version supports PyCapsule interface (#24029)
  • Make Series init consistent with DataFrame init for string values declared with temporal dtype (#24785)
  • Support MergeSorted in CSPE (#24805)
  • Duration/interval string parsing optimisation (2-5x faster) (#24771)
  • Recursively apply CSPE (#24798)
  • Add streaming engine per-node metrics (#24788)
  • Add arr.eval (#24472)
  • Drop PyArrow requirement for non-batched usage of read_database with the ADBC engine and support iter_batches with the ADBC engine (#24180)
  • Improve rolling_(sum|mean) accuracy (#24743)
  • Add separator to {Data,Lazy}Frame.unnest (#24716)
  • Add union() function for unordered concatenation (#24298)
  • Add name.replace to the set of column rename options (#17942)
  • Support np.ndarray -> AnyValue conversion (#24748)
  • Allow duration strings with leading "+" (#24737)
  • Drop now-unnecessary post-init "schema_overrides" cast on DataFrame load from list of dicts (#24739)
  • Add support for UInt128 to pyo3-polars (#24731)
🐞 Bug fixes
  • Re-enable CPU feature check before import (#25010)
  • Implement read_excel workaround for fastexcel/calamine issue loading a column subset from a named table (#25012)
  • Correctness any(ignore_nulls) and OOB in all (#25005)
  • Streaming any/all with ignore_nulls=False (#25008)
  • Fix incorrect join_asof on a casted expression (#25006)
  • Optimize memory on rolling groups in ApplyExpr (#24709)
  • Fallback Pyarrow scan to in-memory engine (#24991)
  • Make Operator::swap_operands return correct operators for Plus, Minus, Multiply and Divide (#24997)
  • Capitalize letters after numbers in to_titlecase (#24993)
  • Preserve null values in pct_change (#24952)
  • Raise length mismatch on over with sliced groups (#24887)
  • Check duplicate name in transpose (#24956)
  • Follow Kleene logic in any / all for group-by (#24940)
  • Do not optimize cross join to iejoin if order maintaining (#24950)
  • Fix typing of scan_parquet partially unknown (#24928)
  • Properly release the GIL for read_parquet_metadata (#24922)
  • Broadcast partition_by columns in over expression (#24874)
  • Clear index cache on stacked df.filter expressions (#24870)
  • Fix 'explode' mapping strategy on scalar value (#24861)
  • Fix repeated with_row_index() after scan() silently ignored (#24866)
  • Correctly return min and max for enums in groupby aggregation (#24808)
  • Refactor BinaryExpr in group_by dispatch logic (#24548)
  • Fix aggstate for gather (#24857)
  • Keep scalars for length preserving functions in group_by (#24819)
  • Have range feature depend on dtype-array feature (#24853)
  • Fix duplicate select panic (#24836)
  • Inconsistency of list.sum() result type with None values (#24476)
  • Division by zero in Expr.dt.truncate (#24832)
  • Potential deadlock in __arrow_c_stream__ (#24831)
  • Allow double aggregations in group-by contexts (#24823)
  • Series.shrink_dtype for i128/u128 (#24833)
  • Fix dtype in EvalExpr (#24650)
  • Allow aggregations on AggState::LiteralScalar (#24820)
  • Dispatch to group_aware for fallible expressions with masked out elements (#24815)
  • Fix error for arr.sum() on small integer Array dtypes containing nulls (#24478)
  • Fix regression on write_database() to Snowflake due to unsupported string view type (#24622)
  • Fix XOR did not follow kleene when one side is unit-length (#24810)
  • Make Series init consistent with DataFrame init for string values declared with temporal dtype (#24785)
  • Incorrect precision in Series.str.to_decimal (#24804)
  • Use overlapping instead of rolling (#24787)
  • Fix iterable on dynamic_group_by and rolling object (#24740)
  • Use Kahan summation for in-memory groupby sum/mean (#24774)
  • Release GIL in PythonScan predicate evaluation (#24779)
  • Type error in bitmask::nth_set_bit_u64 (#24775)
  • Add Expr.sign for Decimal datatype (#24717)
  • Correct str.replace with missing pattern (#24768)
  • Ensure schema_overrides is respected when loading iterable row data (#24721)
  • Support decimal_comma on Decimal type in write_csv (#24718)
📖 Documentation
  • Introduce remote Polars MCP server (#24977)
  • Add {arr,list}.agg API references (#24970)
  • Support LLM in docs (#24958)
  • Update Cloud docs with correct fn argument order (#24939)
  • Update name.replace examples (#24941)
  • Add i128 and u128 features to user guide (#24938)
  • Add partitioning examples for sink_* methods (#24918)
  • Add more {unique,value}_counts examples (#24927)
  • Indent the versionchanged (#24783)
  • Relax fsspec wording (#24881)
  • Add pl.field into the api docs (#24846)
  • Fix duplicated article in SECURITY.md (#24762)
  • Document output name determination in when/then/otherwise (#24746)
  • Specify that precision=None becomes 38 for Decimal (#24742)
  • Mention polars[rt64] and polars[rtcompat] instead of u64-idx and lts-cpu (#24749)
  • Fix source mapping (#24736)
📦 Build system
  • Ensure build_feature_flags.py is included in artifact (#25024)
  • Update pyo3 and numpy crates to version 0.26 (#24760)
🛠️ Other improvements
  • Fix benchmark ci (#25019)
  • Fix non-deterministic test (#25009)
  • Fix makefile arch detection (#25011)
  • Make LazyFrame.set_sorted into a FunctionIR::Hint (#24981)
  • Remove symbolic links (#24982)
  • Deprecate Expr.agg_groups() and pl.groups() (#24919)
  • Dispatch to no-op rayon thread-pool from streaming (#24957)
  • Unpin pydantic (#24955)
  • Ensure safety of scan fast-count IR lowering in streaming (#24953)
  • Re-use iterators in set_ operations (#24850)
  • Remove GroupByPartitioned and dispatch to streaming engine (#24903)
  • Turn element() into {A,}Expr::Element (#24885)
  • Pass ScanOptions to new_from_ipc (#24893)
  • Update tests to be index type agnostic (#24891)
  • Unset Context in Window expression (#24875)
  • Fix failing delta test (#24867)
  • Move FunctionExpr dispatch from plan to expr (#24839)
  • Fix SQL test giving wrong error message (#24835)
  • Consolidate dtype paths in ApplyExpr (#24825)
  • Add days_in_month to documentation (#24822)
  • Enable ruff D417 lint (#24814)
  • Turn pl.format into proper elementwise expression (#24811)
  • Fix remote benchmark by no-longer saving builds (#24812)
  • Refactor ApplyExpr in group_by context on multiple inputs (#24520)
  • IR text plan graph generator (#24733)
  • Temporarily pin pydantic to fix CI (#24797)
  • Extend and rename rolling groups to overlapping (#24577)
  • Refactor DataType proptest strategies (#24763)
  • Add union to documentation (#24769)

Thank you to all our contributors for making this release possible! @EndPositive, @EnricoMi, @JakubValtar, @Kevin-Patyk, @MarcoGorelli, @Object905, @alexander-beedie, @borchero, @carnarez, @cmdlineluser, @coastalwhite, @craigalodon, @dsprenkels, @eitsupi, @etrotta, @henryharbeck, @jordanosborn, @kdn36, @math-hiyoko, @mjanssen, @nameexhaustion, @orlp, @pavelzw, @r-brink, @ritchie46, @thomasjpfan and @williambdean

View originalPermalink
How 1.35.0 went
1.35.0-beta.1Pre-release

Python Polars 1.35.0-beta.1

Added 8
  • Add environment variable to roundtrip empty struct in Parquet
  • Add glob parameter to scan_ipc
  • Add list.agg and arr.agg
  • Implement {Expr,Series}.rolling_rank()
  • Add arr.eval
  • Add separator to {Data,Lazy}Frame.unnest
  • Add union() function for unordered concatenation
  • Add name.replace to the set of column rename options
Changed 11
  • Address group_by_dynamic slowness in sparse data
  • Push filters to PyIceberg
  • Implement native filter/drop_nulls/drop_nans in group-by context
  • Implement cumulative_eval using the group-by engine
  • Prevent generation of copies of Dataframes in DslPlan serialization
  • Implement native null_count, any and all group-by aggregations
Fixed 1
  • Fix repeated with_row_index() after scan() silently ignored
🚀 Performance improvements
  • Address group_by_dynamic slowness in sparse data (#24916)
  • Push filters to PyIceberg (#24910)
  • Native filter/drop_nulls/drop_nans in group-by context (#24897)
  • Implement cumulative_eval using the group-by engine (#24889)
  • Prevent generation of copies of Dataframes in DslPlan serialization (#24852)
  • Implement native null_count, any and all group-by aggregations (#24859)
  • Speed up reverse in group-by context (#24855)
  • Prune unused categorical values when exporting to arrow/parquet/IPC/pickle (#24829)
  • Don't check duplicates on streaming simple projection in release mode (#24830)
  • Lower approx_n_unique to the streaming engine (#24821)
  • Duration/interval string parsing optimisation (2-5x faster) (#24771)
  • Use native reducer for first/last on Decimals, Categoricals and Enums (#24786)
  • Implement indexed method for BitMapIter::nth (#24766)
  • Pushdown slices on plans within unions (#24735)
✨ Enhancements
  • Add environment variable to roundtrip empty struct in Parquet (#24914)
  • Fast-count for scan_iceberg().select(len()) (#24602)
  • Add glob parameter to scan_ipc (#24898)
  • Prevent generation of copies of Dataframes in DslPlan serialization (#24852)
  • Add list.agg and arr.agg (#24790)
  • Implement {Expr,Series}.rolling_rank() (#24776)
  • Don't require PyArrow for read_database_uri if ADBC engine version supports PyCapsule interface (#24029)
  • Make Series init consistent with DataFrame init for string values declared with temporal dtype (#24785)
  • Support MergeSorted in CSPE (#24805)
  • Duration/interval string parsing optimisation (2-5x faster) (#24771)
  • Recursively apply CSPE (#24798)
  • Add streaming engine per-node metrics (#24788)
  • Add arr.eval (#24472)
  • Drop PyArrow requirement for non-batched usage of read_database with the ADBC engine and support iter_batches with the ADBC engine (#24180)
  • Improve rolling_(sum|mean) accuracy (#24743)
  • Add separator to {Data,Lazy}Frame.unnest (#24716)
  • Add union() function for unordered concatenation (#24298)
  • Add name.replace to the set of column rename options (#17942)
  • Support np.ndarray -> AnyValue conversion (#24748)
  • Allow duration strings with leading "+" (#24737)
  • Drop now-unnecessary post-init "schema_overrides" cast on DataFrame load from list of dicts (#24739)
  • Add support for UInt128 to pyo3-polars (#24731)
🐞 Bug fixes
  • Properly release the GIL for read_parquet_metadata (#24922)
  • Broadcast partition_by columns in over expression (#24874)
  • Clear index cache on stacked df.filter expressions (#24870)
  • Fix 'explode' mapping strategy on scalar value (#24861)
  • Fix repeated with_row_index() after scan() silently ignored (#24866)
  • Correctly return min and max for enums in groupby aggregation (#24808)
  • Refactor BinaryExpr in group_by dispatch logic (#24548)
  • Fix aggstate for gather (#24857)
  • Keep scalars for length preserving functions in group_by (#24819)
  • Have range feature depend on dtype-array feature (#24853)
  • Fix duplicate select panic (#24836)
  • Inconsistency of list.sum() result type with None values (#24476)
  • Division by zero in Expr.dt.truncate (#24832)
  • Potential deadlock in __arrow_c_stream__ (#24831)
  • Allow double aggregations in group-by contexts (#24823)
  • Series.shrink_dtype for i128/u128 (#24833)
  • Fix dtype in EvalExpr (#24650)
  • Allow aggregations on AggState::LiteralScalar (#24820)
  • Dispatch to group_aware for fallible expressions with masked out elements (#24815)
  • Fix error for arr.sum() on small integer Array dtypes containing nulls (#24478)
  • Fix regression on write_database() to Snowflake due to unsupported string view type (#24622)
  • Fix XOR did not follow kleene when one side is unit-length (#24810)
  • Make Series init consistent with DataFrame init for string values declared with temporal dtype (#24785)
  • Incorrect precision in Series.str.to_decimal (#24804)
  • Use overlapping instead of rolling (#24787)
  • Fix iterable on dynamic_group_by and rolling object (#24740)
  • Use Kahan summation for in-memory groupby sum/mean (#24774)
  • Release GIL in PythonScan predicate evaluation (#24779)
  • Type error in bitmask::nth_set_bit_u64 (#24775)
  • Add Expr.sign for Decimal datatype (#24717)
  • Correct str.replace with missing pattern (#24768)
  • Ensure schema_overrides is respected when loading iterable row data (#24721)
  • Support decimal_comma on Decimal type in write_csv (#24718)
📖 Documentation
  • Add partitioning examples for sink_* methods (#24918)
  • Add more {unique,value}_counts examples (#24927)
  • Indent the versionchanged (#24783)
  • Relax fsspec wording (#24881)
  • Add pl.field into the api docs (#24846)
  • Fix duplicated article in SECURITY.md (#24762)
  • Document output name determination in when/then/otherwise (#24746)
  • Specify that precision=None becomes 38 for Decimal (#24742)
  • Mention polars[rt64] and polars[rtcompat] instead of u64-idx and lts-cpu (#24749)
  • Fix source mapping (#24736)
📦 Build system
  • Update pyo3 and numpy crates to version 0.26 (#24760)
🛠️ Other improvements
  • Re-use iterators in set_ operations (#24850)
  • Remove GroupByPartitioned and dispatch to streaming engine (#24903)
  • Turn element() into {A,}Expr::Element (#24885)
  • Pass ScanOptions to new_from_ipc (#24893)
  • Update tests to be index type agnostic (#24891)
  • Unset Context in Window expression (#24875)
  • Fix failing delta test (#24867)
  • Move FunctionExpr dispatch from plan to expr (#24839)
  • Fix SQL test giving wrong error message (#24835)
  • Consolidate dtype paths in ApplyExpr (#24825)
  • Add days_in_month to documentation (#24822)
  • Enable ruff D417 lint (#24814)
  • Turn pl.format into proper elementwise expression (#24811)
  • Fix remote benchmark by no-longer saving builds (#24812)
  • Refactor ApplyExpr in group_by context on multiple inputs (#24520)
  • IR text plan graph generator (#24733)
  • Temporarily pin pydantic to fix CI (#24797)
  • Extend and rename rolling groups to overlapping (#24577)
  • Refactor DataType proptest strategies (#24763)
  • Add union to documentation (#24769)

Thank you to all our contributors for making this release possible! @JakubValtar, @Kevin-Patyk, @MarcoGorelli, @Object905, @alexander-beedie, @borchero, @cmdlineluser, @coastalwhite, @craigalodon, @dsprenkels, @eitsupi, @etrotta, @henryharbeck, @jordanosborn, @kdn36, @math-hiyoko, @nameexhaustion, @orlp, @pavelzw, @ritchie46, @thomasjpfan and @williambdean

View originalPermalink
How 1.35.0-beta.1 went
1.34.0

Python Polars 1.34.0

Added 7
  • Add LazyFrame.sink_batches and LazyFrame.collect_batches
  • Add support to output dt.total_{}() duration values as fractionals
  • Add support for unsigned 128-bit integers
  • Add unstable pl.Config.set_default_credential_provider
  • Add opt-in unstable functionality to load interval types as Struct
  • Add support for unique / n_unique / arg_unique for array columns
  • Add unstable hidden_file_prefix parameter to scan_parquet
Changed 9
  • Deterministic import order for Python Polars package variants
  • Implement maintain_order for cross join
  • Avoid forcing a pyarrow dependency in read_excel when using the default calamine engine
  • Support scanning from file:/path URIs
  • Add support to display lazy query plan in marimo notebooks without needing to install matplotlib or mermaid
  • Use fixed-scale Decimals
Fixed 3
  • Parse Decimal with comma as decimal separator in CSV
  • Make Categories pickleable
  • Fix handling of AggregatedScalar in ApplyExpr single input
🏆 Highlights
  • Add LazyFrame.{sink,collect}_batches (#23980)
  • Deterministic import order for Python Polars package variants (#24531)
🚀 Performance improvements
  • Optimize gather_every(n=1) to slice (#24704)
  • Lower null count to streaming engine (#24703)
  • Native streaming gather_every (#24700)
  • Pushdown filter with strptime if input is literal (#24694)
  • Avoid copying expanded paths (#24669)
  • Relax filter expr ordering (#24662)
  • Remove unnecessary groups call in aggregated (#24651)
  • Skip files in scan_iceberg with filter based on metadata statistics (#24547)
  • Push row_index predicate for all scan types (#24537)
  • Perform integer in-filtering for Parquet inequality predicates (#24525)
  • Stop caching Parquet metadata after 8 files (#24513)
  • Native streaming .mode() expression (#24459)
✨ Enhancements
  • Implement maintain_order for cross join (#24665)
  • Add support to output dt.total_{}() duration values as fractionals (#24598)
  • Avoid forcing a pyarrow dependency in read_excel when using the default "calamine" engine (#24655)
  • Support scanning from file:/path URIs (#24603)
  • Log which file the schema was sourced from, and which file caused an extra column error (#24621)
  • Add LazyFrame.{sink,collect}_batches (#23980)
  • Deterministic import order for Python Polars package variants (#24531)
  • Add support to display lazy query plan in marimo notebooks without needing to install matplotlib or mermaid (#24540)
  • Add unstable hidden_file_prefix parameter to scan_parquet (#24507)
  • Use fixed-scale Decimals (#24542)
  • Add support for unsigned 128-bit integers (#24346)
  • Add unstable pl.Config.set_default_credential_provider (#24434)
  • Roundtrip BinaryOffset type through Parquet (#24344)
  • Add opt-in unstable functionality to load interval types as Struct (#24320)
  • Support reading parquet metadata from cloud storage (#24443)
  • Add user guide section on AWS role assumption (#24421)
  • Support unique / n_unique / arg_unique for array columns (#24406)
🐞 Bug fixes
  • Removing dots after noqa comments (#24722)
  • Parse Decimal with comma as decimal separator in CSV (#24685)
  • Make Categories pickleable (#24691)
  • Shift on array within list (#24678)
  • Fix handling of AggregatedScalar in ApplyExpr single input (#24634)
  • Support reading of mixed compressed/uncompressed IPC buffers (#24674)
  • Overflow in slice-slice optimization (#24658)
  • Package discovery for setuptools (#24656)
  • Add type assertion to prevent out-of-bounds in GenericFirstLastGroupedReduction (#24590)
  • Remove inclusion of polars dir in runtime sdist/wheel (#24654)
  • Method dt.month_end was unnecessarily raising when the month-start timestamp was ambiguous (#24647)
  • Widen from_dicts to Iterable[Mapping[str, Any]] (#24584)
  • Fix unsupported arrow type Dictionary error in scan_iceberg() (#24573)
  • Raise Exception instead of panic when unnest on non-struct column (#24471)
  • Include missing feature dependency from polars-stream/diff to polars-plan/abs (#24613)
  • Newline escaping in streaming show_graph (#24612)
  • Do not allow inferring (-1) the dimension on any Expr.reshape dimension except the first (#24591)
  • Sink batches early stop on in-memory engine (#24585)
  • More precisely model expression ordering requirements (#24437)
  • Panic in zero-weight rolling mean/var (#24596)
  • Decimal <-> literal arithmetic supertype rules (#24594)
  • Match various aggregation return types in the streaming engine with the in-memory engine (#24501)
  • Validate list type for list expressions in planner (#24589)
  • Fix scan_iceberg() storage options not taking effect (#24574)
  • Have log() prioritize the leftmost dtype for its output dtype (#24581)
  • CSV pl.len() was incorrect (#24587)
  • Add support for float inputs for duration types (#24529)
  • Roundtrip empty string through hive partitioning (#24546)
  • Fix potential OOB writes in unaligned IPC read (#24550)
  • Fix regression error when scanning AWS presigned URL (#24530)
  • Make PlPath::join for cloud paths replace on absolute paths (#24514)
  • Correct dtype for cum_agg in streaming engine (#24510)
  • Restore support for np.datetime64() in pl.lit() (#24527)
  • Ignore Iceberg list element ID if missing (#24479)
  • Fix panic on streaming full join with coalesce (#23409)
  • Fix AggState on all_literal in BinaryExpr (#24461)
  • Show IR sort options in explain (#24465)
  • Benchmark CI import (#24463)
  • Fix schema on ApplyExpr with single row literal in agg context (#24422)
  • Fix planner schema for dividing pl.Float32 by int (#24432)
  • Fix panic scanning from AWS legacy global endpoint URL (#24450)
  • Fix iterable_to_pydf(..., infer_schema_length=None) to scan all data (#23405)
  • Do not propagate struct of nulls with null (#24420)
  • Be stricter with invalid NDJSON input when ignore_errors=False (#24404)
  • Implement approx_n_unique for temporal dtypes and Null (#24417)
📖 Documentation
  • Add default parquet compression levels (#24686)
  • Fix syntax error in data-types-and-structures.md (#24606)
  • Rename avg_birthday -> avg_age in examples aggregation (#23726)
  • Update Polars Cloud user guide (#24366)
  • Fix typo in set_expr_depth_warning docstring (#24427)
📦 Build system
  • Python pre-release 1.34.0b5 (#24699)
  • Use cargo-run to call dsl-schema script (#24607)
🛠️ Other improvements
  • Removing dots after noqa comments (#24722)
  • Make test_multiple_sorting_columns test runnable (#24719)
  • Remove {Upper,Lower}Bound expressions in IR (#24701)
  • Fix Makefile uv pip option syntax (#24711)
  • Add egg-info to gitignore (#24712)
  • Restructure python project directories again (#24676)
  • Use IR for polars-expr output field resolution (#24661)
  • Remove dist/ from release python workflow (#24639)
  • Escape sed ampersand in release script (#24631)
  • Remove PyOdide from release for now (#24630)
  • Fix sed in-place in release script (#24628)
  • Release script pyodide wheel (#24627)
  • Release script pyodide wheel (#24626)
  • Update release script for runtimes (#24610)
  • Remove unused UnknownKind::Ufunc (#24614)
  • Use cargo-run to call dsl-schema script (#24607)
  • Cleanup and prepare to_field for element and struct field context (#24592)
  • Resolve nightly clippy hints (#24593)
  • Rename pl.dependencies to pl._dependencies (#24595)
  • More release scripting (#24582)
  • Again a minor fix for the setup script (#24580)
  • Minor fix in release script (#24579)
  • Correct release python beta version check (#24578)
  • Python dependency failure (#24576)
  • Always install yq (#24570)
  • Deterministic import order for Python Polars package variants (#24531)
  • Check Arrow FFI pointers with an assert (#24564)
  • Add a couple of missing type definitions in python (#24561)
  • Fix quickstart example in Polars Cloud user guide (#24554)
  • Add implementations for loading min/max statistics for Iceberg (#24496)
  • Update versions (#24508)
  • Add additional unit tests for pl.concat (#24487)
  • Refactor parametric tests for as_struct on aggstates (#24493)
  • Use PlanCallback in name.map_* (#24484)
  • Pin xlsvwriter to 3.2.5 or before (#24485)
  • Add dataclass to hold resolved iceberg scan data (#24418)
  • Fix iceberg test failure in CI (#24456)
  • Move CompressionUtils to polars-utils (#24430)
  • Update github template to dispatch to cloud client (#24416)

Thank you to all our contributors for making this release possible! @DeflateAwning, @Gusabary, @JakubValtar, @Kevin-Patyk, @MarcoGorelli, @Matt711, @alexander-beedie, @alonsosilvaallende, @andreseje, @borchero, @c-peters, @camriddell, @coastalwhite, @dangotbanned, @deanm0000, @dongchao-1, @dsprenkels, @eitsupi, @itamarst, @jan-krueger, @joshuamarkovic, @juansolm, @kdn36, @moizescbf, @nameexhaustion, @orlp, @r-brink, @ritchie46 and @stijnherfst

View originalPermalink
How 1.34.0 went
1.34.0-beta.5Pre-release

Python Polars 1.34.0-beta.5

Added 10
  • Add LazyFrame.sink_batches and LazyFrame.collect_batches
  • Add support to output dt.total_{}() duration values as fractionals
  • Add unstable hidden_file_prefix parameter to scan_parquet
  • Add support for unsigned 128-bit integers
  • Add unstable pl.Config.set_default_credential_provider
  • Add opt-in unstable functionality to load interval types as Struct
Changed 5
  • Implement maintain_order for cross join
  • Deterministic import order for Python Polars package variants
  • Avoid forcing a pyarrow dependency in read_excel when using the default calamine engine
  • Use fixed-scale Decimals
  • Roundtrip BinaryOffset type through Parquet
Fixed 5
  • Make Categories pickleable
  • Shift on array within list
  • Support reading of mixed compressed/uncompressed IPC buffers
  • Overflow in slice-slice optimization
  • Method dt.month_end was unnecessarily raising when the month-start timestamp was ambiguous
🏆 Highlights
  • Add LazyFrame.{sink,collect}_batches (#23980)
  • Deterministic import order for Python Polars package variants (#24531)
🚀 Performance improvements
  • Pushdown filter with strptime if input is literal (#24694)
  • Avoid copying expanded paths (#24669)
  • Relax filter expr ordering (#24662)
  • Remove unnecessary groups call in aggregated (#24651)
  • Skip files in scan_iceberg with filter based on metadata statistics (#24547)
  • Push row_index predicate for all scan types (#24537)
  • Perform integer in-filtering for Parquet inequality predicates (#24525)
  • Stop caching Parquet metadata after 8 files (#24513)
  • Native streaming .mode() expression (#24459)
✨ Enhancements
  • Implement maintain_order for cross join (#24665)
  • Add support to output dt.total_{}() duration values as fractionals (#24598)
  • Avoid forcing a pyarrow dependency in read_excel when using the default "calamine" engine (#24655)
  • Support scanning from file:/path URIs (#24603)
  • Log which file the schema was sourced from, and which file caused an extra column error (#24621)
  • Add LazyFrame.{sink,collect}_batches (#23980)
  • Deterministic import order for Python Polars package variants (#24531)
  • Add support to display lazy query plan in marimo notebooks without needing to install matplotlib or mermaid (#24540)
  • Add unstable hidden_file_prefix parameter to scan_parquet (#24507)
  • Use fixed-scale Decimals (#24542)
  • Add support for unsigned 128-bit integers (#24346)
  • Add unstable pl.Config.set_default_credential_provider (#24434)
  • Roundtrip BinaryOffset type through Parquet (#24344)
  • Add opt-in unstable functionality to load interval types as Struct (#24320)
  • Support reading parquet metadata from cloud storage (#24443)
  • Add user guide section on AWS role assumption (#24421)
  • Support unique / n_unique / arg_unique for array columns (#24406)
🐞 Bug fixes
  • Make Categories pickleable (#24691)
  • Shift on array within list (#24678)
  • Fix handling of AggregatedScalar in ApplyExpr single input (#24634)
  • Support reading of mixed compressed/uncompressed IPC buffers (#24674)
  • Overflow in slice-slice optimization (#24658)
  • Package discovery for setuptools (#24656)
  • Add type assertion to prevent out-of-bounds in GenericFirstLastGroupedReduction (#24590)
  • Remove inclusion of polars dir in runtime sdist/wheel (#24654)
  • Method dt.month_end was unnecessarily raising when the month-start timestamp was ambiguous (#24647)
  • Widen from_dicts to Iterable[Mapping[str, Any]] (#24584)
  • Fix unsupported arrow type Dictionary error in scan_iceberg() (#24573)
  • Raise Exception instead of panic when unnest on non-struct column (#24471)
  • Include missing feature dependency from polars-stream/diff to polars-plan/abs (#24613)
  • Newline escaping in streaming show_graph (#24612)
  • Do not allow inferring (-1) the dimension on any Expr.reshape dimension except the first (#24591)
  • Sink batches early stop on in-memory engine (#24585)
  • More precisely model expression ordering requirements (#24437)
  • Panic in zero-weight rolling mean/var (#24596)
  • Decimal <-> literal arithmetic supertype rules (#24594)
  • Match various aggregation return types in the streaming engine with the in-memory engine (#24501)
  • Validate list type for list expressions in planner (#24589)
  • Fix scan_iceberg() storage options not taking effect (#24574)
  • Have log() prioritize the leftmost dtype for its output dtype (#24581)
  • CSV pl.len() was incorrect (#24587)
  • Add support for float inputs for duration types (#24529)
  • Roundtrip empty string through hive partitioning (#24546)
  • Fix potential OOB writes in unaligned IPC read (#24550)
  • Fix regression error when scanning AWS presigned URL (#24530)
  • Make PlPath::join for cloud paths replace on absolute paths (#24514)
  • Correct dtype for cum_agg in streaming engine (#24510)
  • Restore support for np.datetime64() in pl.lit() (#24527)
  • Ignore Iceberg list element ID if missing (#24479)
  • Fix panic on streaming full join with coalesce (#23409)
  • Fix AggState on all_literal in BinaryExpr (#24461)
  • Show IR sort options in explain (#24465)
  • Benchmark CI import (#24463)
  • Fix schema on ApplyExpr with single row literal in agg context (#24422)
  • Fix planner schema for dividing pl.Float32 by int (#24432)
  • Fix panic scanning from AWS legacy global endpoint URL (#24450)
  • Fix iterable_to_pydf(..., infer_schema_length=None) to scan all data (#23405)
  • Do not propagate struct of nulls with null (#24420)
  • Be stricter with invalid NDJSON input when ignore_errors=False (#24404)
  • Implement approx_n_unique for temporal dtypes and Null (#24417)
📖 Documentation
  • Add default parquet compression levels (#24686)
  • Fix syntax error in data-types-and-structures.md (#24606)
  • Rename avg_birthday -> avg_age in examples aggregation (#23726)
  • Update Polars Cloud user guide (#24366)
  • Fix typo in set_expr_depth_warning docstring (#24427)
📦 Build system
  • Python pre-release 1.34.0b5 (#24699)
  • Use cargo-run to call dsl-schema script (#24607)
🛠️ Other improvements
  • Restructure python project directories again (#24676)
  • Use IR for polars-expr output field resolution (#24661)
  • Remove dist/ from release python workflow (#24639)
  • Escape sed ampersand in release script (#24631)
  • Remove PyOdide from release for now (#24630)
  • Fix sed in-place in release script (#24628)
  • Release script pyodide wheel (#24627)
  • Release script pyodide wheel (#24626)
  • Update release script for runtimes (#24610)
  • Remove unused UnknownKind::Ufunc (#24614)
  • Use cargo-run to call dsl-schema script (#24607)
  • Cleanup and prepare to_field for element and struct field context (#24592)
  • Resolve nightly clippy hints (#24593)
  • Rename pl.dependencies to pl._dependencies (#24595)
  • More release scripting (#24582)
  • Again a minor fix for the setup script (#24580)
  • Minor fix in release script (#24579)
  • Correct release python beta version check (#24578)
  • Python dependency failure (#24576)
  • Always install yq (#24570)
  • Deterministic import order for Python Polars package variants (#24531)
  • Check Arrow FFI pointers with an assert (#24564)
  • Add a couple of missing type definitions in python (#24561)
  • Fix quickstart example in Polars Cloud user guide (#24554)
  • Add implementations for loading min/max statistics for Iceberg (#24496)
  • Update versions (#24508)
  • Add additional unit tests for pl.concat (#24487)
  • Refactor parametric tests for as_struct on aggstates (#24493)
  • Use PlanCallback in name.map_* (#24484)
  • Pin xlsvwriter to 3.2.5 or before (#24485)
  • Add dataclass to hold resolved iceberg scan data (#24418)
  • Fix iceberg test failure in CI (#24456)
  • Move CompressionUtils to polars-utils (#24430)
  • Update github template to dispatch to cloud client (#24416)

Thank you to all our contributors for making this release possible! @DeflateAwning, @Gusabary, @JakubValtar, @Kevin-Patyk, @MarcoGorelli, @Matt711, @alexander-beedie, @alonsosilvaallende, @borchero, @c-peters, @camriddell, @coastalwhite, @dangotbanned, @deanm0000, @dongchao-1, @dsprenkels, @eitsupi, @itamarst, @jan-krueger, @joshuamarkovic, @juansolm, @kdn36, @moizescbf, @nameexhaustion, @orlp, @r-brink, @ritchie46 and @stijnherfst

View originalPermalink
How 1.34.0-beta.5 went
1.34.0-beta.4Pre-release

Python Polars 1.34.0-beta.4

Added 9
  • Add LazyFrame.sink_batches and LazyFrame.collect_batches
  • Support scanning from file:/path URIs
  • Add unstable hidden_file_prefix parameter to scan_parquet
  • Add support for unsigned 128-bit integers
  • Add unstable pl.Config.set_default_credential_provider
  • Add opt-in unstable functionality to load interval types as Struct
Changed 8
  • Deterministic import order for Python Polars package variants
  • Use fixed-scale Decimals
  • Roundtrip BinaryOffset type through Parquet
  • Skip files in scan_iceberg with filter based on metadata statistics
  • Push row_index predicate for all scan types
  • Perform integer in-filtering for Parquet inequality predicates
  • Stop caching Parquet metadata after 8 files
  • Native streaming .mode() expression
Fixed 4
  • Fix unsupported arrow type Dictionary error in scan_iceberg()
  • Raise Exception instead of panic when unnest on non-struct column
  • Fix scan_iceberg() storage options not taking effect
  • Fix regression error when scanning AWS presigned URL
🏆 Highlights
  • Add LazyFrame.{sink,collect}_batches (#23980)
  • Deterministic import order for Python Polars package variants (#24531)
🚀 Performance improvements
  • Skip files in scan_iceberg with filter based on metadata statistics (#24547)
  • Push row_index predicate for all scan types (#24537)
  • Perform integer in-filtering for Parquet inequality predicates (#24525)
  • Stop caching Parquet metadata after 8 files (#24513)
  • Native streaming .mode() expression (#24459)
✨ Enhancements
  • Support scanning from file:/path URIs (#24603)
  • Log which file the schema was sourced from, and which file caused an extra column error (#24621)
  • Add LazyFrame.{sink,collect}_batches (#23980)
  • Deterministic import order for Python Polars package variants (#24531)
  • Add support to display lazy query plan in marimo notebooks without needing to install matplotlib or mermaid (#24540)
  • Add unstable hidden_file_prefix parameter to scan_parquet (#24507)
  • Use fixed-scale Decimals (#24542)
  • Add support for unsigned 128-bit integers (#24346)
  • Add unstable pl.Config.set_default_credential_provider (#24434)
  • Roundtrip BinaryOffset type through Parquet (#24344)
  • Add opt-in unstable functionality to load interval types as Struct (#24320)
  • Support reading parquet metadata from cloud storage (#24443)
  • Add user guide section on AWS role assumption (#24421)
  • Support unique / n_unique / arg_unique for array columns (#24406)
🐞 Bug fixes
  • Widen from_dicts to Iterable[Mapping[str, Any]] (#24584)
  • Fix unsupported arrow type Dictionary error in scan_iceberg() (#24573)
  • Raise Exception instead of panic when unnest on non-struct column (#24471)
  • Include missing feature dependency from polars-stream/diff to polars-plan/abs (#24613)
  • Newline escaping in streaming show_graph (#24612)
  • Do not allow inferring (-1) the dimension on any Expr.reshape dimension except the first (#24591)
  • Sink batches early stop on in-memory engine (#24585)
  • More precisely model expression ordering requirements (#24437)
  • Panic in zero-weight rolling mean/var (#24596)
  • Decimal <-> literal arithmetic supertype rules (#24594)
  • Match various aggregation return types in the streaming engine with the in-memory engine (#24501)
  • Validate list type for list expressions in planner (#24589)
  • Fix scan_iceberg() storage options not taking effect (#24574)
  • Have log() prioritize the leftmost dtype for its output dtype (#24581)
  • CSV pl.len() was incorrect (#24587)
  • Add support for float inputs for duration types (#24529)
  • Roundtrip empty string through hive partitioning (#24546)
  • Fix potential OOB writes in unaligned IPC read (#24550)
  • Fix regression error when scanning AWS presigned URL (#24530)
  • Make PlPath::join for cloud paths replace on absolute paths (#24514)
  • Correct dtype for cum_agg in streaming engine (#24510)
  • Restore support for np.datetime64() in pl.lit() (#24527)
  • Ignore Iceberg list element ID if missing (#24479)
  • Fix panic on streaming full join with coalesce (#23409)
  • Fix AggState on all_literal in BinaryExpr (#24461)
  • Show IR sort options in explain (#24465)
  • Benchmark CI import (#24463)
  • Fix schema on ApplyExpr with single row literal in agg context (#24422)
  • Fix planner schema for dividing pl.Float32 by int (#24432)
  • Fix panic scanning from AWS legacy global endpoint URL (#24450)
  • Fix iterable_to_pydf(..., infer_schema_length=None) to scan all data (#23405)
  • Do not propagate struct of nulls with null (#24420)
  • Be stricter with invalid NDJSON input when ignore_errors=False (#24404)
  • Implement approx_n_unique for temporal dtypes and Null (#24417)
📖 Documentation
  • Fix syntax error in data-types-and-structures.md (#24606)
  • Rename avg_birthday -> avg_age in examples aggregation (#23726)
  • Update Polars Cloud user guide (#24366)
  • Fix typo in set_expr_depth_warning docstring (#24427)
📦 Build system
  • Use cargo-run to call dsl-schema script (#24607)
🛠️ Other improvements
  • Remove dist/ from release python workflow (#24639)
  • Escape sed ampersand in release script (#24631)
  • Remove PyOdide from release for now (#24630)
  • Fix sed in-place in release script (#24628)
  • Release script pyodide wheel (#24627)
  • Release script pyodide wheel (#24626)
  • Update release script for runtimes (#24610)
  • Remove unused UnknownKind::Ufunc (#24614)
  • Use cargo-run to call dsl-schema script (#24607)
  • Cleanup and prepare to_field for element and struct field context (#24592)
  • Resolve nightly clippy hints (#24593)
  • Rename pl.dependencies to pl._dependencies (#24595)
  • More release scripting (#24582)
  • Again a minor fix for the setup script (#24580)
  • Minor fix in release script (#24579)
  • Correct release python beta version check (#24578)
  • Python dependency failure (#24576)
  • Always install yq (#24570)
  • Deterministic import order for Python Polars package variants (#24531)
  • Check Arrow FFI pointers with an assert (#24564)
  • Add a couple of missing type definitions in python (#24561)
  • Fix quickstart example in Polars Cloud user guide (#24554)
  • Add implementations for loading min/max statistics for Iceberg (#24496)
  • Update versions (#24508)
  • Add additional unit tests for pl.concat (#24487)
  • Refactor parametric tests for as_struct on aggstates (#24493)
  • Use PlanCallback in name.map_* (#24484)
  • Pin xlsvwriter to 3.2.5 or before (#24485)
  • Add dataclass to hold resolved iceberg scan data (#24418)
  • Fix iceberg test failure in CI (#24456)
  • Move CompressionUtils to polars-utils (#24430)
  • Update github template to dispatch to cloud client (#24416)

Thank you to all our contributors for making this release possible! @Gusabary, @Kevin-Patyk, @Matt711, @MoizesCBF, @alonsosilvaallende, @borchero, @c-peters, @camriddell, @coastalwhite, @dangotbanned, @deanm0000, @dongchao-1, @dsprenkels, @itamarst, @jan-krueger, @joshuamarkovic, @juansolm, @kdn36, @nameexhaustion, @orlp, @r-brink, @ritchie46 and @stijnherfst

View originalPermalink
How 1.34.0-beta.4 went
1.34.0-beta.3Pre-release

Python Polars 1.34.0-beta.3

Added 7
  • Add LazyFrame.sink_batches and LazyFrame.collect_batches methods
  • Add support for unsigned 128-bit integers
  • Add unstable hidden_file_prefix parameter to scan_parquet
  • Add unstable pl.Config.set_default_credential_provider
  • Add opt-in unstable functionality to load interval types as Struct
  • Add support for unique, n_unique, and arg_unique operations for array columns
  • Add support to display lazy query plan in marimo notebooks without needing to install matplotlib or mermaid
Changed 5
  • Deterministic import order for Python Polars package variants
  • Use fixed-scale Decimals
  • Support scanning from file:/path URIs
  • Support reading parquet metadata from cloud storage
  • Roundtrip BinaryOffset type through Parquet
Fixed 8
  • Fix unsupported arrow type Dictionary error in scan_iceberg()
  • Raise Exception instead of panic when unnest on non-struct column
  • Fix scan_iceberg() storage options not taking effect
  • Fix panic on streaming full join with coalesce
  • Fix iterable_to_pydf with infer_schema_length=None to scan all data
  • Restore support for np.datetime64() in pl.lit()
  • Do not allow inferring the dimension on any Expr.reshape dimension except the first
  • Implement approx_n_unique for temporal dtypes and Null
🏆 Highlights
  • Add LazyFrame.{sink,collect}_batches (#23980)
  • Deterministic import order for Python Polars package variants (#24531)
🚀 Performance improvements
  • Skip files in scan_iceberg with filter based on metadata statistics (#24547)
  • Push row_index predicate for all scan types (#24537)
  • Perform integer in-filtering for Parquet inequality predicates (#24525)
  • Stop caching Parquet metadata after 8 files (#24513)
  • Native streaming .mode() expression (#24459)
✨ Enhancements
  • Support scanning from file:/path URIs (#24603)
  • Log which file the schema was sourced from, and which file caused an extra column error (#24621)
  • Add LazyFrame.{sink,collect}_batches (#23980)
  • Deterministic import order for Python Polars package variants (#24531)
  • Add support to display lazy query plan in marimo notebooks without needing to install matplotlib or mermaid (#24540)
  • Add unstable hidden_file_prefix parameter to scan_parquet (#24507)
  • Use fixed-scale Decimals (#24542)
  • Add support for unsigned 128-bit integers (#24346)
  • Add unstable pl.Config.set_default_credential_provider (#24434)
  • Roundtrip BinaryOffset type through Parquet (#24344)
  • Add opt-in unstable functionality to load interval types as Struct (#24320)
  • Support reading parquet metadata from cloud storage (#24443)
  • Add user guide section on AWS role assumption (#24421)
  • Support unique / n_unique / arg_unique for array columns (#24406)
🐞 Bug fixes
  • Widen from_dicts to Iterable[Mapping[str, Any]] (#24584)
  • Fix unsupported arrow type Dictionary error in scan_iceberg() (#24573)
  • Raise Exception instead of panic when unnest on non-struct column (#24471)
  • Include missing feature dependency from polars-stream/diff to polars-plan/abs (#24613)
  • Newline escaping in streaming show_graph (#24612)
  • Do not allow inferring (-1) the dimension on any Expr.reshape dimension except the first (#24591)
  • Sink batches early stop on in-memory engine (#24585)
  • More precisely model expression ordering requirements (#24437)
  • Panic in zero-weight rolling mean/var (#24596)
  • Decimal <-> literal arithmetic supertype rules (#24594)
  • Match various aggregation return types in the streaming engine with the in-memory engine (#24501)
  • Validate list type for list expressions in planner (#24589)
  • Fix scan_iceberg() storage options not taking effect (#24574)
  • Have log() prioritize the leftmost dtype for its output dtype (#24581)
  • CSV pl.len() was incorrect (#24587)
  • Add support for float inputs for duration types (#24529)
  • Roundtrip empty string through hive partitioning (#24546)
  • Fix potential OOB writes in unaligned IPC read (#24550)
  • Fix regression error when scanning AWS presigned URL (#24530)
  • Make PlPath::join for cloud paths replace on absolute paths (#24514)
  • Correct dtype for cum_agg in streaming engine (#24510)
  • Restore support for np.datetime64() in pl.lit() (#24527)
  • Ignore Iceberg list element ID if missing (#24479)
  • Fix panic on streaming full join with coalesce (#23409)
  • Fix AggState on all_literal in BinaryExpr (#24461)
  • Show IR sort options in explain (#24465)
  • Benchmark CI import (#24463)
  • Fix schema on ApplyExpr with single row literal in agg context (#24422)
  • Fix planner schema for dividing pl.Float32 by int (#24432)
  • Fix panic scanning from AWS legacy global endpoint URL (#24450)
  • Fix iterable_to_pydf(..., infer_schema_length=None) to scan all data (#23405)
  • Do not propagate struct of nulls with null (#24420)
  • Be stricter with invalid NDJSON input when ignore_errors=False (#24404)
  • Implement approx_n_unique for temporal dtypes and Null (#24417)
📖 Documentation
  • Fix syntax error in data-types-and-structures.md (#24606)
  • Rename avg_birthday -> avg_age in examples aggregation (#23726)
  • Update Polars Cloud user guide (#24366)
  • Fix typo in set_expr_depth_warning docstring (#24427)
📦 Build system
  • Use cargo-run to call dsl-schema script (#24607)
🛠️ Other improvements
  • Remove dist/ from release python workflow (#24639)
  • Escape sed ampersand in release script (#24631)
  • Remove PyOdide from release for now (#24630)
  • Fix sed in-place in release script (#24628)
  • Release script pyodide wheel (#24627)
  • Release script pyodide wheel (#24626)
  • Update release script for runtimes (#24610)
  • Remove unused UnknownKind::Ufunc (#24614)
  • Use cargo-run to call dsl-schema script (#24607)
  • Cleanup and prepare to_field for element and struct field context (#24592)
  • Resolve nightly clippy hints (#24593)
  • Rename pl.dependencies to pl._dependencies (#24595)
  • More release scripting (#24582)
  • Again a minor fix for the setup script (#24580)
  • Minor fix in release script (#24579)
  • Correct release python beta version check (#24578)
  • Python dependency failure (#24576)
  • Always install yq (#24570)
  • Deterministic import order for Python Polars package variants (#24531)
  • Check Arrow FFI pointers with an assert (#24564)
  • Add a couple of missing type definitions in python (#24561)
  • Fix quickstart example in Polars Cloud user guide (#24554)
  • Add implementations for loading min/max statistics for Iceberg (#24496)
  • Update versions (#24508)
  • Add additional unit tests for pl.concat (#24487)
  • Refactor parametric tests for as_struct on aggstates (#24493)
  • Use PlanCallback in name.map_* (#24484)
  • Pin xlsvwriter to 3.2.5 or before (#24485)
  • Add dataclass to hold resolved iceberg scan data (#24418)
  • Fix iceberg test failure in CI (#24456)
  • Move CompressionUtils to polars-utils (#24430)
  • Update github template to dispatch to cloud client (#24416)

Thank you to all our contributors for making this release possible! @Gusabary, @Kevin-Patyk, @Matt711, @MoizesCBF, @alonsosilvaallende, @borchero, @c-peters, @camriddell, @coastalwhite, @dangotbanned, @deanm0000, @dongchao-1, @dsprenkels, @itamarst, @jan-krueger, @joshuamarkovic, @juansolm, @kdn36, @nameexhaustion, @orlp, @r-brink, @ritchie46 and @stijnherfst

View originalPermalink
How 1.34.0-beta.3 went
1.34.0-beta.1Pre-release

Python Polars 1.34.0-beta.1

Added 8
  • Add LazyFrame.sink_batches and LazyFrame.collect_batches
  • Add support to display lazy query plan in marimo notebooks without needing to install matplotlib or mermaid
  • Add unstable hidden_file_prefix parameter to scan_parquet
  • Add support for unsigned 128-bit integers
  • Add unstable pl.Config.set_default_credential_provider
  • Add opt-in unstable functionality to load interval types as Struct
  • Support reading parquet metadata from cloud storage
  • Support unique / n_unique / arg_unique for array columns
Changed 8
  • Use fixed-scale Decimals
  • Roundtrip BinaryOffset type through Parquet
  • Deterministic import order for Python Polars package variants
  • Skip files in scan_iceberg with filter based on metadata statistics
  • Push row_index predicate for all scan types
  • Perform integer in-filtering for Parquet inequality predicates
  • Stop caching Parquet metadata after 8 files
  • Native streaming .mode() expression
Fixed 4
  • Add support for float inputs for duration types
  • Roundtrip empty string through hive partitioning
  • Fix potential OOB writes in unaligned IPC read
  • Fix regression error when scanning AWS presigned URL
🏆 Highlights
  • Add LazyFrame.{sink,collect}_batches (#23980)
  • Deterministic import order for Python Polars package variants (#24531)
🚀 Performance improvements
  • Skip files in scan_iceberg with filter based on metadata statistics (#24547)
  • Push row_index predicate for all scan types (#24537)
  • Perform integer in-filtering for Parquet inequality predicates (#24525)
  • Stop caching Parquet metadata after 8 files (#24513)
  • Native streaming .mode() expression (#24459)
✨ Enhancements
  • Add LazyFrame.{sink,collect}_batches (#23980)
  • Deterministic import order for Python Polars package variants (#24531)
  • Add support to display lazy query plan in marimo notebooks without needing to install matplotlib or mermaid (#24540)
  • Add unstable hidden_file_prefix parameter to scan_parquet (#24507)
  • Use fixed-scale Decimals (#24542)
  • Add support for unsigned 128-bit integers (#24346)
  • Add unstable pl.Config.set_default_credential_provider (#24434)
  • Roundtrip BinaryOffset type through Parquet (#24344)
  • Add opt-in unstable functionality to load interval types as Struct (#24320)
  • Support reading parquet metadata from cloud storage (#24443)
  • Add user guide section on AWS role assumption (#24421)
  • Support unique / n_unique / arg_unique for array columns (#24406)
🐞 Bug fixes
  • Add support for float inputs for duration types (#24529)
  • Roundtrip empty string through hive partitioning (#24546)
  • Fix potential OOB writes in unaligned IPC read (#24550)
  • Fix regression error when scanning AWS presigned URL (#24530)
  • Make PlPath::join for cloud paths replace on absolute paths (#24514)
  • Correct dtype for cum_agg in streaming engine (#24510)
  • Restore support for np.datetime64() in pl.lit() (#24527)
  • Ignore Iceberg list element ID if missing (#24479)
  • Fix panic on streaming full join with coalesce (#23409)
  • Fix AggState on all_literal in BinaryExpr (#24461)
  • Show IR sort options in explain (#24465)
  • Benchmark CI import (#24463)
  • Fix schema on ApplyExpr with single row literal in agg context (#24422)
  • Fix planner schema for dividing pl.Float32 by int (#24432)
  • Fix panic scanning from AWS legacy global endpoint URL (#24450)
  • Fix iterable_to_pydf(..., infer_schema_length=None) to scan all data (#23405)
  • Do not propagate struct of nulls with null (#24420)
  • Be stricter with invalid NDJSON input when ignore_errors=False (#24404)
  • Implement approx_n_unique for temporal dtypes and Null (#24417)
📖 Documentation
  • Rename avg_birthday -> avg_age in examples aggregation (#23726)
  • Update Polars Cloud user guide (#24366)
  • Fix typo in set_expr_depth_warning docstring (#24427)
🛠️ Other improvements
  • More release scripting (#24582)
  • Again a minor fix for the setup script (#24580)
  • Minor fix in release script (#24579)
  • Correct release python beta version check (#24578)
  • Python dependency failure (#24576)
  • Always install yq (#24570)
  • Deterministic import order for Python Polars package variants (#24531)
  • Check Arrow FFI pointers with an assert (#24564)
  • Add a couple of missing type definitions in python (#24561)
  • Fix quickstart example in Polars Cloud user guide (#24554)
  • Add implementations for loading min/max statistics for Iceberg (#24496)
  • Update versions (#24508)
  • Add additional unit tests for pl.concat (#24487)
  • Refactor parametric tests for as_struct on aggstates (#24493)
  • Use PlanCallback in name.map_* (#24484)
  • Pin xlsvwriter to 3.2.5 or before (#24485)
  • Add dataclass to hold resolved iceberg scan data (#24418)
  • Fix iceberg test failure in CI (#24456)
  • Move CompressionUtils to polars-utils (#24430)
  • Update github template to dispatch to cloud client (#24416)

Thank you to all our contributors for making this release possible! @Gusabary, @Kevin-Patyk, @Matt711, @alonsosilvaallende, @borchero, @c-peters, @camriddell, @coastalwhite, @dongchao-1, @dsprenkels, @itamarst, @jan-krueger, @joshuamarkovic, @juansolm, @kdn36, @nameexhaustion, @orlp, @r-brink, @ritchie46 and @stijnherfst

View originalPermalink
How 1.34.0-beta.1 went
1.33.1

Python Polars 1.33.1

Added 5
  • Support S3 virtual-hosted–style URI
  • Add PyCapsule `__arrow_c_schema__` interface to `pl.Schema`
  • Support Partitioning sinks in cloud
  • User-friendly error message on empty path expansion
  • Add unstable `pre_execution_query` parameter to `read_database_uri`
Changed 5
  • Use specialized decoding for all predicates for Parquet dictionary encoding
  • Allocate only for read items when reading Parquet with predicate
  • Don't aggregate groups for strict cast if original len
  • Remove explicit file create for local async writes
  • Enable all integer dtypes for `by` parameter in `join_asof`
Fixed 10
  • Correct `sink_ipc` overload for compression
  • Fix Group-By + filter aggregation performs subsequent operations on all data instead of only filtered data
  • Wrap deprecated top-level imports in TYPE_CHECKING
  • Fix incorrect output ordering for row-separable exprs
  • Fix `Series.__arrow_c_stream__` for Decimal and other logical types
  • Match output type to engine for `Struct` arithmetic
🚀 Performance improvements
  • Use specialized decoding for all predicates for Parquet dictionary encoding (#24403)
  • Allocate only for read items when reading Parquet with predicate (#24401)
  • Don't aggregate groups for strict cast if original len (#24381)
  • Allocate only for read items when reading Parquet with predicate (#24324)
✨ Enhancements
  • Support S3 virtual-hosted–style URI (#24405)
  • Remove explicit file create for local async writes (#24358)
  • Add PyCapsule __arrow_c_schema__ interface to pl.Schema (#24365)
  • Support Partitioning sinks in cloud (#24399)
  • User-friendly error message on empty path expansion (#24337)
  • Add unstable pre_execution_query parameter to read_database_uri (#23634)
  • Add Polars security policy (#24314)
🐞 Bug fixes
  • Correct sink_ipc overload for compression (#24398)
  • Enable all integer dtypes for by parameter in join_asof (#24384)
  • Fix Group-By + filter aggregation performs subsequent operations on all data instead of only filtered data (#24373)
  • Wrap deprecated top-level imports in TYPE_CHECKING (#24340)
  • Fix incorrect output ordering for row-separable exprs (#24354)
  • Fix Series.__arrow_c_stream__ for Decimal and other logical types (#24120)
  • Match output type to engine for Struct arithmetic (#23805)
  • Make mmap use MAP_PRIVATE rather than MAP_SHARED (#24343)
  • Fix cloud iceberg scan DATASET_PROVIDER_VTABLE error (#24338)
  • Don't throw away type information for NumPy numeric values when using lit() (#24229)
  • Incorrect logic in negative streaming slice (#24326)
  • Ensure read_database_uri with ADBC works as expected with DuckDB URIs (#24097)
  • Do not error on non-list Sequence for columns parameter in read_excel (#23967)
📖 Documentation
  • Document newly added is_pure parameter for register_io_source (#24311)
  • Create a module docstring for the public polars module (#24332)
  • Update to Polars Cloud user guide (#24187)
  • Update distributed page (#24323)
  • Add a note and example about exporting unformatted Excel sheet data (#24145)
  • Add detail about server-side cursor behaviour for SQLAlchemy in the "iter_batches" parameter of read_database (#24094)
  • Add Polars security policy (#24314)
🛠️ Other improvements
  • Bump c-api (#24412)
  • Add a regression test for #7631 (#24363)
  • Update cloud test InteractiveQuery to DirectQuery (#24287)
  • Mark some tests as slow (#24327)
  • Mark more tests as ready for cloud (#24315)
  • Add hint to update PYPOLARS_VERSION on version assert test (#24313)

Thank you to all our contributors for making this release possible! @Kevin-Patyk, @VictorAtIfInsurance, @alexander-beedie, @coastalwhite, @dsprenkels, @itamarst, @kdn36, @kuril, @mcrumiller, @nameexhaustion, @nesb1, @orlp, @r-brink and @ritchie46

View originalPermalink
How 1.33.1 went
1.33.0

Python Polars 1.33.0

Added 7
  • Add CSE for custom io sources using pointer for hashing
  • Add caching to user credential providers
  • Expose mkdir parameter on write_parquet
  • Add LazyFrame.pipe_with_schema
  • Add cum_* as native streaming nodes
  • Add peak_{min,max} support for booleans
  • Add DataFrame.map_columns for eager evaluation
Changed 10
  • Native streaming int_range with len or count
  • Lower arg_unique natively to the streaming engine
  • Lower arg_where natively to streaming engine
  • Lower Expr.shift to streaming engine
  • Lower order-preserving groupby to streaming engine
  • Allow pl.Expr.log to take in an expression
Fixed 1
  • Invalid conversion from non-bit numpy bools
Removed 1
  • Remove, deprecate or change eager Exprs to be lazy compatible
Deprecated 1
  • Add a deprecation warning for pl.Series.shift(Null)
💥 Breaking changes
  • Remove, deprecate or change eager Exprs to be lazy compatible (#24027)
🚀 Performance improvements
  • Native streaming int_range with len or count (#24280)
  • Lower arg_unique natively to the streaming engine (#24279)
  • Move unordering optimization to end (#24286)
  • Do ordering simplification step after common sub-plan elimination (#24269)
  • Always simplify order requirements in IR (#24192)
  • Basic de-duplication of filter expressions (#24220)
  • Cache the IR in pipe_with_schema (#24213)
  • Lower arg_where natively to streaming engine (#24088)
  • Lower Expr.shift to streaming engine (#24106)
  • Lower order-preserving groupby to streaming engine (#24053)
✨ Enhancements
  • Add CSE for custom io sources using pointer for hashing (#24297)
  • Allow pl.Expr.log to take in an expression (#24226)
  • Add caching to user credential providers (#23789)
  • Expose mkdir parameter on write_parquet (#24239)
  • Implement diff() in streaming engine (#24189)
  • Enable Expr.diff(n) for negative n (#24200)
  • Allow upcasting null-typed columns to nested column types in scans (#24185)
  • Log pyarrow predicate conversion result in sensitive verbose logs (#24186)
  • Drop PyArrow requirement for write_database with the ADBC engine (#24136)
  • Add a deprecation warning for pl.Series.shift(Null) (#24114)
  • Improve Debug formatting of DataType (#24056)
  • Add LazyFrame.pipe_with_schema (#24075)
  • Catch additional temporal attributes in BytecodeParser function analysis (#24076)
  • Add cum_* as native streaming nodes (#23977)
  • Add peak_{min,max} support for booleans (#24068)
  • Add DataFrame.map_columns for eager evaluation (#23821)
🐞 Bug fixes
  • Invalid conversion from non-bit numpy bools (#24312)
  • Make dt.epoch('s') serializable (#24302)
  • Make Expr.rechunk serializable (#24303)
  • Schema mismatch for 'log' operation (#24300)
  • Incorrect first/last aggregate in streaming engine (#24289)
  • Fix group offsets in sliced groups (#24274)
  • Panic in inexact date(time) conversion (#24268)
  • Keep DSL cache after serialization and deserialization (#24265)
  • Sanitize and warn about eval usage (#24262)
  • Correct incorrect default in from_pandas overload for include_index (#24258)
  • Unique with keep="none" in new optimization pass (#24261)
  • Correct size limits for Decimal cast (#24252)
  • Unordered unions in check order observing pass (#24253)
  • Fix dtype for slice on Literal in agg context (#24137)
  • Fix incorrect filter(lit(True)) when scanning hive (#24237)
  • In-memory group_by on 128-bit integers (#24242)
  • Fix panic in gather inside groupby with invalid indices (#24182)
  • Release the GIL in map_groups (#24225)
  • Remove extra explode in LazyGroupBy.{head,tail} (#24221)
  • Fix panic in polars cloud CSV scan (#24197)
  • Fix panic when loading categorical columns from IO plugin (#24205)
  • Fix credential provider did not auto-init on partition sinks (#24188)
  • Fix engine type for concat_list on AggScalar implode (#24160)
  • Rolling_mean handle centered weights with len(values) < window_size (#24158)
  • Reading is_in predicate for Parquet plain strings (#24184)
  • Support native DuckDB connection in read_database (#24177)
  • Make PyCategories pickleable (#24170)
  • Remove unused unsound function to_mutable_slice (#24173)
  • PyO3 extension types giving compat_level errors (#24166)
  • Allow non-elementwise by in top_k (#24164)
  • Fix sort_by for group_by_dynamic context (#24152)
  • Input-independent length aggregations in streaming (#24153)
  • Release GIL when iterating df in to_arrow (#24151)
  • Respect non-elementwise join_where conditions (#24135)
  • Fix mismatched pytest test collection error (#24133)
  • Resolve schema mismatch for div on Boolean (#24111)
  • Fix from_repr parsing of negative durations (#24115)
  • Make group_by/partition_by iterator keys tuple[Any, ...] to enable tuple-unpacking (#24113)
  • Keep name when doing empty group-aware aggregation (#24098)
  • Implode instead of reshape_list (#24078)
  • Rolling mean with weights incorrect when min_samples < window_size (#23485)
  • Allow merge_sorted for all types (#24077)
  • Include datatypes in row_encode expression (#24074)
  • Include UDF materialized type in serialization (#24073)
  • Correct .rolling() output type for non-aggregations (#24072)
  • Correct planner output schema for join_asof (#24071)
  • Correct output for fold and reduce (#24069)
  • Expr.meta.output_name for struct fields (#24064)
  • Ensure upcast operations on pl.Date default to microsecond precision (#23981)
  • Add peak_{min,max} support for booleans (#24068)
  • Planner output type for mean with strange input type (#24052)
  • Remove, deprecate or change eager Exprs to be lazy compatible (#24027)
📖 Documentation
  • Fix few typos (#24305)
  • Add missing reference to LazyFrame.pipe_with_schema() on the website (#24285)
  • Automatically register doctest.ELLIPSIS so we don't have to add the inline directive each time (#24146)
  • Update categorical comparison documentation in user guide (#24249)
  • Add missing references for Seriers.rolling_*_by methods (#24254)
  • Fix formatting of Series.value_counts examples (#24245)
  • Add hint to use DataFrame/Series constructors in from_arrow docstring (#22942)
  • Update GPU un/supported features (#24195)
  • Add DataFrame.map_columns to API (#24128)
  • Update multiple pages in the Polars Cloud user guide (#23661)
  • Fix str.find_many() docstring example (#24092)
📦 Build system
  • Re-enable macos-x86-64 (#24266)
  • Drop binary support for macos_x86-64 (#24257)
🛠️ Other improvements
  • Remove PDS-H code (#24301)
  • Get ready for even more cloud tests (#24292)
  • Add tests for slices with caches (#24288)
  • Readd ordering tests (#24284)
  • Fix Makefile venv path (#24251)
  • Remove unnecessary parentheses (#24244)
  • Make non-nested shift{,_and_fill} ops generic (#24224)
  • Remove unused Wrap (#24214)
  • Allow upcasting null-typed columns to nested column types in scans (#24185)
  • Automatically label a few more types of PR (#24147)
  • Update toolchain (#24156)
  • Add order_sensitive property for AExpr (#24116)
  • Mark more tests as not possible on cloud (#24103)
  • Turn AggExpr::Count from tuple to struct (#24096)
  • Mark tests that may fail in cloud (#24067)
  • Extend read database tests to capture more ADBC functionality (#24002)
  • Make CI perf failures more lenient (#24066)
  • Fix hive partition string encoding in CI by upgrading deltalake (#24018)
  • Make tests with sinks run on cloud again (#24048)

Thank you to all our contributors for making this release possible! @Kevin-Patyk, @MarcoGorelli, @NeejWeej, @agossard, @alexander-beedie, @aparna2198, @borchero, @coastalwhite, @deanm0000, @dsprenkels, @eitsupi, @etiennebacher, @gab23r, @henryharbeck, @jjurm, @kdn36, @math-hiyoko, @mcrumiller, @mroeschke, @nameexhaustion, @orlp, @r-brink, @ritchie46, @stijnherfst, @vdrn and @wence-

View originalPermalink
How 1.33.0 went
1.33.0-beta.1Pre-release

Python Polars 1.33.0-beta.1

Added 11
  • Allow pl.Expr.log to take in an expression
  • Add caching to user credential providers
  • Expose mkdir parameter on write_parquet
  • Implement diff() in streaming engine
  • Enable Expr.diff(n) for negative n
  • Allow upcasting null-typed columns to nested column types in scans
Changed 6
  • Always simplify order requirements in IR
  • Basic de-duplication of filter expressions
  • Cache the IR in pipe_with_schema
  • Lower arg_where natively to streaming engine
  • Lower Expr.shift to streaming engine
  • Lower order-preserving groupby to streaming engine
Fixed 2
  • Correct size limits for Decimal cast
  • Unordered unions in check order observing pass
Removed 1
  • Remove, deprecate or change eager Exprs to be lazy compatible
Deprecated 1
  • Add a deprecation warning for pl.Series.shift(Null)
💥 Breaking changes
  • Remove, deprecate or change eager Exprs to be lazy compatible (#24027)
🚀 Performance improvements
  • Always simplify order requirements in IR (#24192)
  • Basic de-duplication of filter expressions (#24220)
  • Cache the IR in pipe_with_schema (#24213)
  • Lower arg_where natively to streaming engine (#24088)
  • Lower Expr.shift to streaming engine (#24106)
  • Lower order-preserving groupby to streaming engine (#24053)
✨ Enhancements
  • Allow pl.Expr.log to take in an expression (#24226)
  • Add caching to user credential providers (#23789)
  • Expose mkdir parameter on write_parquet (#24239)
  • Implement diff() in streaming engine (#24189)
  • Enable Expr.diff(n) for negative n (#24200)
  • Allow upcasting null-typed columns to nested column types in scans (#24185)
  • Log pyarrow predicate conversion result in sensitive verbose logs (#24186)
  • Drop PyArrow requirement for write_database with the ADBC engine (#24136)
  • Add a deprecation warning for pl.Series.shift(Null) (#24114)
  • Improve Debug formatting of DataType (#24056)
  • Add LazyFrame.pipe_with_schema (#24075)
  • Catch additional temporal attributes in BytecodeParser function analysis (#24076)
  • Add cum_* as native streaming nodes (#23977)
  • Add peak_{min,max} support for booleans (#24068)
  • Add DataFrame.map_columns for eager evaluation (#23821)
🐞 Bug fixes
  • Correct size limits for Decimal cast (#24252)
  • Unordered unions in check order observing pass (#24253)
  • Fix dtype for slice on Literal in agg context (#24137)
  • Fix incorrect filter(lit(True)) when scanning hive (#24237)
  • In-memory group_by on 128-bit integers (#24242)
  • Fix panic in gather inside groupby with invalid indices (#24182)
  • Release the GIL in map_groups (#24225)
  • Remove extra explode in LazyGroupBy.{head,tail} (#24221)
  • Fix panic in polars cloud CSV scan (#24197)
  • Fix panic when loading categorical columns from IO plugin (#24205)
  • Fix credential provider did not auto-init on partition sinks (#24188)
  • Fix engine type for concat_list on AggScalar implode (#24160)
  • Rolling_mean handle centered weights with len(values) < window_size (#24158)
  • Reading is_in predicate for Parquet plain strings (#24184)
  • Support native DuckDB connection in read_database (#24177)
  • Make PyCategories pickleable (#24170)
  • Remove unused unsound function to_mutable_slice (#24173)
  • PyO3 extension types giving compat_level errors (#24166)
  • Allow non-elementwise by in top_k (#24164)
  • Fix sort_by for group_by_dynamic context (#24152)
  • Input-independent length aggregations in streaming (#24153)
  • Release GIL when iterating df in to_arrow (#24151)
  • Respect non-elementwise join_where conditions (#24135)
  • Fix mismatched pytest test collection error (#24133)
  • Resolve schema mismatch for div on Boolean (#24111)
  • Fix from_repr parsing of negative durations (#24115)
  • Make group_by/partition_by iterator keys tuple[Any, ...] to enable tuple-unpacking (#24113)
  • Keep name when doing empty group-aware aggregation (#24098)
  • Implode instead of reshape_list (#24078)
  • Rolling mean with weights incorrect when min_samples < window_size (#23485)
  • Allow merge_sorted for all types (#24077)
  • Include datatypes in row_encode expression (#24074)
  • Include UDF materialized type in serialization (#24073)
  • Correct .rolling() output type for non-aggregations (#24072)
  • Correct planner output schema for join_asof (#24071)
  • Correct output for fold and reduce (#24069)
  • Expr.meta.output_name for struct fields (#24064)
  • Ensure upcast operations on pl.Date default to microsecond precision (#23981)
  • Add peak_{min,max} support for booleans (#24068)
  • Planner output type for mean with strange input type (#24052)
  • Remove, deprecate or change eager Exprs to be lazy compatible (#24027)
📖 Documentation
  • Fix formatting of Series.value_counts examples (#24245)
  • Add hint to use DataFrame/Series constructors in from_arrow docstring (#22942)
  • Update GPU un/supported features (#24195)
  • Add DataFrame.map_columns to API (#24128)
  • Update multiple pages in the Polars Cloud user guide (#23661)
  • Fix str.find_many() docstring example (#24092)
📦 Build system
  • Drop binary support for macos_x86-64 (#24257)
🛠️ Other improvements
  • Remove unnecessary parentheses (#24244)
  • Make non-nested shift{,_and_fill} ops generic (#24224)
  • Remove unused Wrap (#24214)
  • Allow upcasting null-typed columns to nested column types in scans (#24185)
  • Automatically label a few more types of PR (#24147)
  • Update toolchain (#24156)
  • Add order_sensitive property for AExpr (#24116)
  • Mark more tests as not possible on cloud (#24103)
  • Turn AggExpr::Count from tuple to struct (#24096)
  • Mark tests that may fail in cloud (#24067)
  • Extend read database tests to capture more ADBC functionality (#24002)
  • Make CI perf failures more lenient (#24066)
  • Fix hive partition string encoding in CI by upgrading deltalake (#24018)
  • Make tests with sinks run on cloud again (#24048)

Thank you to all our contributors for making this release possible! @Kevin-Patyk, @agossard, @alexander-beedie, @aparna2198, @borchero, @coastalwhite, @deanm0000, @dsprenkels, @henryharbeck, @jjurm, @kdn36, @math-hiyoko, @mcrumiller, @mroeschke, @nameexhaustion, @orlp, @r-brink, @ritchie46, @stijnherfst, @vdrn and @wence-

View originalPermalink
How 1.33.0-beta.1 went
1.32.3

Python Polars 1.32.3

Added 3
  • Add native streaming for peaks_min and peaks_max
  • Add DataTypeExpr.default_value
  • Add support for Int128 to pyo3-polars
Changed 5
  • Lower .sort(maintain_order=True).head() to streaming top_k
  • Lower top-k to streaming engine
  • Allow order pass through Filters and relax to row-separable instead of elementwise
  • IR graph arrows, monospace font, box nodes
  • Lower rle to a native streaming engine node
Fixed 12
  • Scan of multiple sources with null datatype
  • Categorical in nested data in row encoding
  • Missing length update in builder for pl.Array repetition
  • Race condition in global categories init
  • Error when using named functions
  • Don't encode entire CategoricalMapping when going to Arrow
🚀 Performance improvements
  • Lower .sort(maintain_order=True).head() to streaming top_k (#24014)
  • Lower top-k to streaming engine (#23979)
  • Allow order pass through Filters and relax to row-seperable instead of elementwise (#23969)
✨ Enhancements
  • Add native streaming for peaks_{min,max} (#24039)
  • IR graph arrows, monospace font, box nodes (#24021)
  • Add DataTypeExpr.default_value (#23973)
  • Lower rle to a native streaming engine node (#23929)
  • Add support for Int128 to pyo3-polars (#23959)
🐞 Bug fixes
  • Scan of multiple sources with null datatype (#24065)
  • Categorical in nested data in row encoding (#24051)
  • Missing length update in builder for pl.Array repetition (#24055)
  • Race condition in global categories init (#24045)
  • Revert "fix: Don't encode entire CategoricalMapping when going to Arrow (#24036)" (#24044)
  • Error when using named functions (#24041)
  • Don't encode entire CategoricalMapping when going to Arrow (#24036)
  • Fix cast on arithmetic with lit (#23941)
  • Incorrect slice-slice pushdown (#24032)
  • Dedup common cache subplan in IR graph (#24028)
  • Allow join on Decimal in in-memory engine (#24026)
  • Fix datatypes for eval.list in aggregation context (#23911)
  • Allocator capsule fallback panic (#24022)
  • Accept another zlib "magic header" file signature (#24013)
  • Fix truediv dtypes so cast in list.eval is not dropped (#23936)
  • Don't reuse cached return_dtype for expanded map expressions (#24010)
  • Cache id is not a valid dot node id (#24005)
  • Align map_elements with and without return_dtype (#24007)
  • Fix column dtype lifetime for csv_write segfault on Categorical (#23986)
  • Allow serializing LazyGroupBy.map_groups (#23964)
  • Correct allocator name in PyCapsule (#23968)
  • Mismatched types for write function for windows (#23915)
  • Fix unpivot panic when index= column not found (#23958)
📖 Documentation
  • Fix a typo in "lazy/execution" user-guide page (#23983)
🛠️ Other improvements
  • Update pyo3-polars versions (#24031)
  • Remove insert_error_function (#24023)
  • Remove cache hits, clean up in-mem prefill (#24019)
  • Use .venv instead of venv in pyo3-polars examples (#24024)
  • Fix test failing mypy (#24017)
  • Remove outdated comment (#23998)
  • Add a _plr.pyi to remove mypy issues (#23970)
  • Don't define CountStar as dyn OptimizationRule (#23976)
  • Rename atol and rtol to abs_tol and rel_tol (#23961)
  • Introduce Row{Encode,Decode} as FunctionExpr (#23933)
  • Dispatch through pl.map_batches and AnonymousColumnsUdf (#23867)

Thank you to all our contributors for making this release possible! @JakubValtar, @Kevin-Patyk, @borchero, @cmdlineluser, @coastalwhite, @iishutov, @jarondl, @kdn36, @orlp, @rawhuul, @ritchie46 and @stijnherfst

View originalPermalink
How 1.32.3 went
1.32.2

Python Polars 1.32.2

Fixed 1
  • Return correct python package version
🐞 Bug fixes
  • Return correct python package version (#23951)
📖 Documentation
  • Add arr.len() on the website (#23944)

Thank you to all our contributors for making this release possible! @coastalwhite and @etiennebacher

View originalPermalink
How 1.32.2 went
1.32.1

Python Polars 1.32.1

Added 3
  • Implement `dt.days_in_month` function
  • Implement `repeat_by` for `Array` and `Null`
  • Support initializing from `__arrow_c_schema__` protocol in `pl.Schema`
Changed 11
  • Lower `rle_id` to a native streaming node
  • Lower `extend_constant` to the streaming engine
  • Lower `pl.repeat` to streaming engine
  • Lower `unique_counts` and `value_counts` to streaming engine
  • Pass `endpoint_url` loaded from `CredentialProviderAWS` to `scan/write_delta`
  • Dispatch `scan_iceberg` to native by default
Fixed 5
  • Categorical namespace functions fail on `Enum` columns
  • Properly set sumwise complete on filter for missing columns
  • Restore Arrow-FFI-based Python<->Rust conversion in pyo3-polars
  • Group By with filters
  • Fix `read_csv` ignoring Decimal schema for header-only data
Deprecated 1
  • Add DeprecationWarning on passing physical ordering to Categorical
🚀 Performance improvements
  • Optimise BytecodeParser usage from warn_on_inefficient_map (#23809)
  • Lower extend_constant to the streaming engine (#23824)
  • Lower pl.repeat to streaming engine (#23804)
  • Remove redundant clone (#23771)
✨ Enhancements
  • Lower rle_id to a native streaming node (#23894)
  • Pass endpoint_url loaded from CredentialProviderAWS to scan/write_delta (#23812)
  • Dispatch scan_iceberg to native by default (#23912)
  • Lower unique_counts and value_counts to streaming engine (#23890)
  • Support initializing from __arrow_c_schema__ protocol in pl.Schema (#23879)
  • Better handle broken local package environment in show_versions (#23885)
  • Implement dt.days_in_month function (#23119)
  • Making Expr.rolling_*_by methods available to pl.Series (#23742)
  • Fix errors on native scan_iceberg (#23811)
  • Reinterpret binary data to fixed size numerical array (#22840)
  • Make rolling_map serializable (#23848)
  • Ensure CachingCredentialProvider returns copied credentials dict (#23817)
  • Change typing for .remote() from LazyFrameExt to LazyFrameRemote (#23825)
  • Implement repeat_by for Array and Null (#23794)
  • Add DeprecationWarning on passing physical ordering to Categorical (#23779)
  • Pre-filtered decode and row group skipping with Iceberg / Delta / scans with cast options (#23792)
  • Update BytecodeParser opcode awareness for upcoming Python 3.14 (#23782)
🐞 Bug fixes
  • Categorical namespace functions fail on Enum columns (#23925)
  • Properly set sumwise complete on filter for missing columns (#23877)
  • Restore Arrow-FFI-based Python<->Rust conversion in pyo3-polars (#23881)
  • Group By with filters (#23917)
  • Fix read_csv ignoring Decimal schema for header-only data (#23886)
  • Ensure collect() native Iceberg always scans latest when no snapshot_id is given (#23907)
  • Writing List(Array) columns to JSON without panic (#23875)
  • Fill Iceberg missing fields with partition values if present in metadata (#23900)
  • Create file for streaming sink even if unspawned (#23672)
  • Update cloud testing environment (#23908)
  • Parquet filtering on multiple RGs with literal predicate (#23903)
  • Incorrect datatype passed to libc::write (#23904)
  • Properly feature gate TZ_AWARE_RE usage (#23888)
  • Improve identification of "non group-key" aggregates in SQL GROUP BY queries (#23191)
  • Spawning tokio task outside reactor (#23884)
  • Correctly raise DuplicateError on asof_join with suffix="" (#23864)
  • Fix errors on native scan_iceberg (#23811)
  • Fix index out of bounds panic filtering parquet (#23850)
  • Fix error on empty range requests (#23844)
  • Fix handling of hive partitioning hive_start_idx parameter (#23843)
  • Allow encoding of pl.Enum with smaller physicals (#23829)
  • Filter sorted flag from physical in CategoricalChunked (#23827)
  • Remove accidental todo! in repeat node (#23822)
  • Make meta.pop operate on Expr only (#23808)
  • Stack overflow in DslPlan serde (#23801)
  • Clear credentials cached in Python when rebuilding object store (#23756)
  • Datetime selectors with mixed timezone info (#23774)
  • Support i128 in asof join (#23770)
  • Remove sleep for credential refresh (#23768)
📖 Documentation
  • Improve StackOverflow links in contributing guide (#23895)
  • Fix pyo3 documentation page link (#23839)
  • Document the pureness requirements of udfs (#23787)
  • Correct the name.* methods on their removal of aliases (#23773)
📦 Build system
  • Workaround for pyiceberg make requirements on Python 3.13 (#23810)
  • Add pyiceberg to dev dependencies (#23791)
🛠️ Other improvements
  • Ensure clippy and rustfmt run in CI when changing pyo3-polars (#23930)
  • Fix pyo3-polars proc-macro re-exports (#23918)
  • Rewrite evaluate_on_groups for .gather / .get (#23700)
  • Move Python C API to python-polars (#23876)
  • Improve/fix internal LRUCache implementation and move into "_utils" module (#23813)
  • Relax constraint on maximum Python version for numba (#23838)
  • Automatically tag PRs mentioning "SQL" with the appropriate label (#23816)
  • Update typos package (#23818)
  • Fix typos path (#23803)
  • Remove deserialize_with_unknown_fields (#23802)
  • Add pyiceberg to dev dependencies (#23791)
  • Remove old schema file (#23798)
  • Mark more tests as ready for cloud (#23743)
  • Reduce required deps for pyo3-polars (#23761)

Thank you to all our contributors for making this release possible! @JakubValtar, @Kevin-Patyk, @Liyixin95, @alexander-beedie, @cgevans, @cmdlineluser, @coastalwhite, @eitsupi, @gfvioli, @itamarst, @jimmmmmmmmmmmy, @kdn36, @math-hiyoko, @mcrumiller, @mpasa, @mrkn, @nameexhaustion, @orlp, @pka, @pomo-mondreganto, @ritchie46 and @stijnherfst

View originalPermalink
How 1.32.1 went
1.32.0

Python Polars 1.32.0

Added 11
  • Make Selector a concrete part of the DSL
  • Add Python-side caching for credentials and provider auto-initialization
  • Expand on DataTypeExpr
  • Add scalar checks to range expressions
  • Expose POLARS_DOT_SVG_VIEWER to automatically dispatch to SVG viewer
  • Implement mean function in arr namespace
Changed 10
  • Rework Categorical/Enum to use (Frozen)Categories
  • Lower Expr.slice to streaming engine
  • Lower any() and all() to streaming engine
  • Lower row-separable functions in streaming engine
  • Lower int_range(len()) to with_row_index
  • Rolling quantile lower time complexity
🏆 Highlights
  • Make Selector a concrete part of the DSL (#23351)
  • Rework Categorical/Enum to use (Frozen)Categories (#23016)
🚀 Performance improvements
  • Lower Expr.slice to streaming engine (#23683)
  • Elide bound check (#23653)
  • Preserve Column repr in ColumnTransform operations (#23648)
  • Lower any() and all() to streaming engine (#23640)
  • Lower row-separable functions in streaming engine (#23633)
  • Lower int_range(len()) to with_row_index (#23576)
  • Avoid double field resolution in with_columns (#23530)
  • Rolling quantile lower time complexity (#23443)
  • Use single-key optimization with Categorical (#23436)
  • Improve null-preserving identification for boolean functions (#23317)
  • Improve boolean bitwise aggregate performance (#23325)
  • Enable Parquet expressions and dedup is_in values in Parquet predicates (#23293)
  • Re-write join types during filter pushdown (#23275)
  • Generate PQ ZSTD decompression context once (#23200)
  • Trigger cache/cse optimizations when multiplexing (#23274)
  • Cache FileInfo upon DSL -> IR conversion (#23263)
  • Push more filters past joins (#23240)
  • Optimize Bitmap::make_mut (#23138)
✨ Enhancements
  • Add Python-side caching for credentials and provider auto-initialization (#23736)
  • Expand on DataTypeExpr (#23249)
  • Lower row-separable functions in streaming engine (#23633)
  • Add scalar checks to range expressions (#23632)
  • Expose POLARS_DOT_SVG_VIEWER to automatically dispatch to SVG viewer (#23592)
  • Implement mean function in arr namespace (#23486)
  • Implement vec_hash for List and Array (#23578)
  • Add unstable pl.row_index() expression (#23556)
  • Add Categories on the Python side (#23543)
  • Implement partitioned sinks for the in-memory engine (#23522)
  • Raise and Warn on UDF's without return_dtype set (#23353)
  • IR pruning (#23499)
  • Support min/max reducer for null dtype in streaming engine (#23465)
  • Implement streaming Categorical/Enum min/max (#23440)
  • Allow cast to Categorical inside list.eval (#23432)
  • Support pathlib.Path as source for read/scan_delta() (#23411)
  • Enable default set of ScanCastOptions for native scan_iceberg() (#23416)
  • Pass payload in ExprRegistry (#23412)
  • Support reading nanosecond/Int96 timestamps and schema evolved datasets in scan_delta() (#23398)
  • Support row group skipping with filters when cast_options is given (#23356)
  • Execute bitwise reductions in streaming engine (#23321)
  • Use scan_parquet().collect_schema() for read_parquet_schema (#23359)
  • Add dtype to str.to_integer() (#22239)
  • Add arr.slice, arr.head and arr.tail methods to arr namespace (#23150)
  • Add is_close method (#23273)
  • Drop superfluous casts from optimized plan (#23269)
  • Added drop_nulls option to to_dummies (#23215)
  • Support comma as decimal separator for CSV write (#23238)
  • Don't format keys if they're empty in dot (#23247)
  • Improve arity simplification (#23242)
  • Allow expression input for length parameter in pad_start, pad_end, and zfill (#23182)
🐞 Bug fixes
  • Load _expiry_time from botocore Credentials in CredentialProviderAWS (#23753)
  • Fix credential refresh logic (#23730)
  • Fix to_datetime() fallible identification (#23735)
  • Correct output datatype for dt.with_time_unit (#23734)
  • Fix incorrect native Iceberg scan from tables with renamed/dropped columns/fields (#23713)
  • Allow DataType expressions with selectors (#23720)
  • Match output type to engine for interpolate on Decimal (#23706)
  • Remaining bugs in with_exprs_and_input and pruning (#23710)
  • Match output dtype to engine for cum_sum_horizontal (#23686)
  • Field names for pl.struct in group-by (#23703)
  • Fix output for str.extract_groups with empty string pattern (#23698)
  • Match output type to engine for rolling_map (#23702)
  • Moved passing DeltaTable._storage_options (#23673)
  • Fix incorrect join on single Int128 column for in-memory engine (#23694)
  • Match output field name to lhs for BusinessDaycount (#23679)
  • Correct the planner output datatype for strptime (#23676)
  • Sort and Scan with_exprs_and_input (#23675)
  • Revert to old behavior with name.keep (#23670)
  • Fix panic loading from arrow Map containing timestamps (#23662)
  • Selectors in self part of list.eval (#23668)
  • Fix output field dtype for ToInteger (#23664)
  • Allow decimal_comma with , separator in read_csv (#23657)
  • Fix handling of UTF-8 in write_csv to IO[str] (#23647)
  • Selectors in {Lazy,Data}Frame.filter (#23631)
  • Stop splitfields iterator at eol in simd branch (#23652)
  • Correct output datatype of dt.year and dt.mil (#23646)
  • Logic of broadcast_rhs in binary functions to correct list.set_intersection for list[str] columns (#23584)
  • Order-preserving equi-join didn't always flush final matches (#23639)
  • Fix ColumnNotFound error when joining on col().cast() (#23622)
  • Fix agg groups on when/then in group_by context (#23628)
  • Output type for sign (#23572)
  • Apply agg_fn on null values in pivot (#23586)
  • Remove nonsensical duration variance (#23621)
  • Don't panic when sinking nested categorical to Parquet (#23610)
  • Correctly set value count output field name (#23611)
  • Casting unused columns in to_torch (#23606)
  • Allow inferring of hours-only timezone offset (#23605)
  • Bug in Categorical <-> str compare with nulls (#23609)
  • Honor n=0 in all cases of str.replace (#23598)
  • Remove arbitrary 25 item limit from implicit Python list -> Series infer (#23603)
  • Relabel duplicate sequence IDs in distributor (#23593)
  • Round-trip Enum and Categorical metadata in plugins (#23588)
  • Fix incorrect join_asof with by followed by head/slice (#23585)
  • Change return typing of get_index_type() from DataType to PolarsIntegerType (#23558)
  • Allow writing nested Int128 data to Parquet (#23580)
  • Enum serialization assert (#23574)
  • Output type for peak_min / peak_max (#23573)
  • Make Scalar Categorical, Enum and Struct values serializable (#23565)
  • Preserve row order within partition when sinking parquet (#23462)
  • Prevent in-mem partition sink deadlock (#23562)
  • Update AWS cloud documentation (#23563)
  • Correctly handle null values when comparing structs (#23560)
  • Make fold/reduce/cum_reduce/cum_fold serializable (#23524)
  • Make Expr.append serializable (#23515)
  • Float by float division dtype (#23529)
  • Division on empty DataFrame generating null row (#23516)
  • Partition sink copy_exprs and with_exprs_and_input (#23511)
  • Unreachable with pl.self_dtype (#23507)
  • Rolling median incorrect min_samples with nulls (#23481)
  • Make Int128 roundtrippable via Parquet (#23494)
  • Fix panic when common subplans contain IEJoins (#23487)
  • Properly handle non-finite floats in rolling_sum/mean (#23482)
  • Make read_csv_batched respect skip_rows and skip_lines (#23484)
  • Always use cloudpickle for the python objects in cloud plans (#23474)
  • Support string literals in index_of() on categoricals (#23458)
  • Don't panic for finish_callback with nested datatypes (#23464)
  • Pass DeltaTable._storage_options if no storage_options are provided (#23456)
  • Support min/max aggregation for DataFrame/LazyFrame Categoricals (#23455)
  • Fix var/moment dtypes (#23453)
  • Fix agg_groups dtype (#23450)
  • Fix incorrect _get_path_scheme (#23444)
  • Fix missing overload defaults in read_ods and tree_format (#23442)
  • Clear cached_schema when apply changes dtype (#23439)
  • Allow structured conversion to/from numpy with Array types, preserving shape (#23438)
  • Null handling in full-null group_by_dynamic mean/sum (#23435)
  • Enable default set of ScanCastOptions for native scan_iceberg() (#23416)
  • Fix index calculation for nearest interpolation (#23418)
  • Overload for eager default in Schema.to_frame was False instead of True (#23413)
  • Fix read_excel overloads so that passing list[str] to sheet_name does not raise (#23388)
  • Removed special handling for bytes like objects in read_ndjson (#23361)
  • Parse parquet footer length into unsigned integer (#23357)
  • Fix incorrect results with group_by aggregation on empty groups (#23358)
  • Fix boolean min() in group_by aggregation (streaming) (#23344)
  • Respect data-model in map_elements (#23340)
  • Properly join URI paths in PlPath (#23350)
  • Ignore null values in bitwise aggregation on bools (#23324)
  • Fix panic filtering after left join (#23310)
  • Out-of-bounds index in hot hash table (#23311)
  • Fix scanning '?' from cloud with glob=False (#23304)
  • Fix filters on inserted columns did not remove rows (#23303)
  • Don't ignore return_dtype (#23309)
  • Raise error instead of return in Series class (#23301)
  • Use safe parsing for get_normal_components (#23284)
  • Fix output column names/order of streaming coalesced right-join (#23278)
  • Restore concat_arr inputs expansion (#23271)
  • Expose FieldsMapper (#23232)
  • Fix time zone handling in dt.iso_year and dt.is_leap_year (#23125)
📖 Documentation
  • Fix str.replace_many examples trigger deprecation warning (#23695)
  • Point the R Polars version on R-multiverse (#23660)
  • Update example for writing to cloud storage (#20265)
  • Update GPU docs for RAPIDS CUDA 11 deprecation (#23620)
  • Add docs of Expr.list.filter and Series.list.filter (#23589)
  • Add page about billing to Polars Cloud user guide (#23564)
  • Small user-guide improvement and fixes (#23549)
  • Correct note in from_pandas about data being cloned (#23552)
  • Fix a few typos in the "Streaming" section (#23536)
  • Update streaming page (#23535)
  • Update structure of Polars Cloud documentation (#23496)
  • Update example code in pandas migration guide (#23403)
  • Correct plugins user guide to reflect that teaching Expr.language is in a different section (#23377)
  • Add example of using OR in join_where (#23375)
  • Update when_then in user guide (#23245)
📦 Build system
  • Update all rand code (#23387)
🛠️ Other improvements
  • Remove unused functions from the rust side (#23757)
  • Add hashes json (#23758)
  • Add AExpr::is_expr_equal_to (#23740)
  • Fix rank test to respect maintain order (#23723)
  • IR inputs and exprs iterators (#23722)
  • Store more granular schema hashes to reduce merge conflicts (#23709)
  • Use UUID for UniqueID (#23704)
  • Remove scan id (#23697)
  • Propagate Iceberg physical ID schema to IR (#23671)
  • Remove unused and confusing match arm (#23691)
  • Remove unused ALLOW_GROUP_AWARE flag (#23690)
  • Remove unused evaluate_inline (#23687)
  • Remove unused field from AggregationContext (#23685)
  • Remove node_to_lp (#23678)
  • Fix cloud bytes scanning and read_* functions (#23642)
  • Group By maintain order on test (#23643)
  • Add maintain_order tests for streaming joins (#23577)
  • Continue on cloud testing (#23616)
  • Add pyo3-polars (#23571)
  • Remove _fetch (#23607)
  • Replace agg_list in AExpr::to_field with is_scalar_ae (#23582)
  • Mark select test case as write_disk (#23566)
  • Rolling order checking of test (#23568)
  • Multiple in-mem plans with reused cache #23561 (#23567)
  • Reduce warning in docs serve (#23534)
  • Remove left-behind print statement (#23533)
  • Make list.to_struct and arr.to_struct serializable (#23504)
  • Small conftest improvement (#23508)
  • Improve Categories error message (#23510)
  • Add test to ensure the global categories gets cleaned up (#23502)
  • Add more testing to group_by sorted test (#23500)
  • Pruning follow-up (#23501)
  • Make arg_min, arg_max, arg_sort and product into concrete DSL and IR constructs (#23493)
  • Simpify arena iterators (#23495)
  • Remove unnecessary may_fail_auto_streaming (#23477)
  • Remove StringCache from the test suite (#23473)
  • Make Selector a concrete part of the DSL (#23351)
  • Add streaming engine to code-coverage (#23441)
  • Remove hashbrown_nightly_hack (#23445)
  • Rework Categorical/Enum to use (Frozen)Categories (#23016)
  • Fix typing error from new pandas-stubs release (#23414)
  • Ignore Sort if 'by' is empty (#23320)
  • Rename from_buffer()/FromBuffer to reinterpret()/Reinterpret (#23362)
  • Only conver to ExprIR once in with_columns (#23352)
  • Update rust version in nix flake (#23347)
  • Update toolchain and fix clippy issues (#23334)
  • Improve cloud tests (#23312)
  • Casting from binview to primitives code moved from polars-ops to polars-compute (#23234)
  • Improve DSL source cache (#23282)
  • Add new PlPath that abstracts over PathBuf and URI (#23280)
  • Add may_fail_cloud mark for pytest (#23279)
  • Organize dsl_to_ir logic into modules (#23277)
  • Add flag for auto distributed testing (#23220)
  • Remove unused PyDataType (#23265)
  • Split FileScan in FileScanDsl and FileScanIR (#23260)
  • Update Rust Polars versions (#23239)
  • Connect Python assert_dataframe_equal() to Rust back-end (#23207)
  • Fix time zone handling in dt.iso_year and dt.is_leap_year (#23125)
  • Update Rust Polars versions (#23229)

Thank you to all our contributors for making this release possible! @Declow, @JakubValtar, @Kevin-Patyk, @Liyixin95, @MarcoGorelli, @Matt711, @TheLostLambda, @Washiil, @borchero, @c-peters, @cmdlineluser, @coastalwhite, @deanm0000, @eitsupi, @etiennebacher, @florian-klein, @gfvioli, @habaneraa, @itamarst, @kdn36, @ldhwaddell, @math-hiyoko, @mcrumiller, @mrkn, @nameexhaustion, @orlp, @othijssens, @r-brink, @ritchie46, @stijnherfst and @zyctree

View originalPermalink
How 1.32.0 went
1.32.0-beta.1Pre-release

Python Polars 1.32.0-beta.1

Added 12
  • Make Selector a concrete part of the DSL
  • Add Python-side caching for credentials and provider auto-initialization
  • Expose POLARS_DOT_SVG_VIEWER to automatically dispatch to SVG viewer
  • Implement mean function in arr namespace
  • Implement vec_hash for List and Array
  • Add unstable pl.row_index() expression
Changed 7
  • Rework Categorical/Enum to use (Frozen)Categories
  • Lower Expr.slice to streaming engine
  • Lower any() and all() to streaming engine
  • Lower row-separable functions in streaming engine
  • Preserve Column repr in ColumnTransform operations
  • Rolling quantile lower time complexity
  • Use single-key optimization with Categorical
Fixed 2
  • Fix credential refresh logic
  • Allow DataType expressions with selectors
🏆 Highlights
  • Make Selector a concrete part of the DSL (#23351)
  • Rework Categorical/Enum to use (Frozen)Categories (#23016)
🚀 Performance improvements
  • Lower Expr.slice to streaming engine (#23683)
  • Elide bound check (#23653)
  • Preserve Column repr in ColumnTransform operations (#23648)
  • Lower any() and all() to streaming engine (#23640)
  • Lower row-separable functions in streaming engine (#23633)
  • Lower int_range(len()) to with_row_index (#23576)
  • Avoid double field resolution in with_columns (#23530)
  • Rolling quantile lower time complexity (#23443)
  • Use single-key optimization with Categorical (#23436)
  • Improve null-preserving identification for boolean functions (#23317)
  • Improve boolean bitwise aggregate performance (#23325)
  • Enable Parquet expressions and dedup is_in values in Parquet predicates (#23293)
  • Re-write join types during filter pushdown (#23275)
  • Generate PQ ZSTD decompression context once (#23200)
  • Trigger cache/cse optimizations when multiplexing (#23274)
  • Cache FileInfo upon DSL -> IR conversion (#23263)
  • Push more filters past joins (#23240)
  • Optimize Bitmap::make_mut (#23138)
✨ Enhancements
  • Add Python-side caching for credentials and provider auto-initialization (#23736)
  • Expand on DataTypeExpr (#23249)
  • Lower row-separable functions in streaming engine (#23633)
  • Add scalar checks to range expressions (#23632)
  • Expose POLARS_DOT_SVG_VIEWER to automatically dispatch to SVG viewer (#23592)
  • Implement mean function in arr namespace (#23486)
  • Implement vec_hash for List and Array (#23578)
  • Add unstable pl.row_index() expression (#23556)
  • Add Categories on the Python side (#23543)
  • Implement partitioned sinks for the in-memory engine (#23522)
  • Raise and Warn on UDF's without return_dtype set (#23353)
  • IR pruning (#23499)
  • Support min/max reducer for null dtype in streaming engine (#23465)
  • Implement streaming Categorical/Enum min/max (#23440)
  • Allow cast to Categorical inside list.eval (#23432)
  • Support pathlib.Path as source for read/scan_delta() (#23411)
  • Enable default set of ScanCastOptions for native scan_iceberg() (#23416)
  • Pass payload in ExprRegistry (#23412)
  • Support reading nanosecond/Int96 timestamps and schema evolved datasets in scan_delta() (#23398)
  • Support row group skipping with filters when cast_options is given (#23356)
  • Execute bitwise reductions in streaming engine (#23321)
  • Use scan_parquet().collect_schema() for read_parquet_schema (#23359)
  • Add dtype to str.to_integer() (#22239)
  • Add arr.slice, arr.head and arr.tail methods to arr namespace (#23150)
  • Add is_close method (#23273)
  • Drop superfluous casts from optimized plan (#23269)
  • Added drop_nulls option to to_dummies (#23215)
  • Support comma as decimal separator for CSV write (#23238)
  • Don't format keys if they're empty in dot (#23247)
  • Improve arity simplification (#23242)
  • Allow expression input for length parameter in pad_start, pad_end, and zfill (#23182)
🐞 Bug fixes
  • Load _expiry_time from botocore Credentials in CredentialProviderAWS (#23753)
  • Fix credential refresh logic (#23730)
  • Fix to_datetime() fallible identification (#23735)
  • Correct output datatype for dt.with_time_unit (#23734)
  • Fix incorrect native Iceberg scan from tables with renamed/dropped columns/fields (#23713)
  • Allow DataType expressions with selectors (#23720)
  • Match output type to engine for interpolate on Decimal (#23706)
  • Remaining bugs in with_exprs_and_input and pruning (#23710)
  • Match output dtype to engine for cum_sum_horizontal (#23686)
  • Field names for pl.struct in group-by (#23703)
  • Fix output for str.extract_groups with empty string pattern (#23698)
  • Match output type to engine for rolling_map (#23702)
  • Moved passing DeltaTable._storage_options (#23673)
  • Fix incorrect join on single Int128 column for in-memory engine (#23694)
  • Match output field name to lhs for BusinessDaycount (#23679)
  • Correct the planner output datatype for strptime (#23676)
  • Sort and Scan with_exprs_and_input (#23675)
  • Revert to old behavior with name.keep (#23670)
  • Fix panic loading from arrow Map containing timestamps (#23662)
  • Selectors in self part of list.eval (#23668)
  • Fix output field dtype for ToInteger (#23664)
  • Allow decimal_comma with , separator in read_csv (#23657)
  • Fix handling of UTF-8 in write_csv to IO[str] (#23647)
  • Selectors in {Lazy,Data}Frame.filter (#23631)
  • Stop splitfields iterator at eol in simd branch (#23652)
  • Correct output datatype of dt.year and dt.mil (#23646)
  • Logic of broadcast_rhs in binary functions to correct list.set_intersection for list[str] columns (#23584)
  • Order-preserving equi-join didn't always flush final matches (#23639)
  • Fix ColumnNotFound error when joining on col().cast() (#23622)
  • Fix agg groups on when/then in group_by context (#23628)
  • Output type for sign (#23572)
  • Apply agg_fn on null values in pivot (#23586)
  • Remove nonsensical duration variance (#23621)
  • Don't panic when sinking nested categorical to Parquet (#23610)
  • Correctly set value count output field name (#23611)
  • Casting unused columns in to_torch (#23606)
  • Allow inferring of hours-only timezone offset (#23605)
  • Bug in Categorical <-> str compare with nulls (#23609)
  • Honor n=0 in all cases of str.replace (#23598)
  • Remove arbitrary 25 item limit from implicit Python list -> Series infer (#23603)
  • Relabel duplicate sequence IDs in distributor (#23593)
  • Round-trip Enum and Categorical metadata in plugins (#23588)
  • Fix incorrect join_asof with by followed by head/slice (#23585)
  • Change return typing of get_index_type() from DataType to PolarsIntegerType (#23558)
  • Allow writing nested Int128 data to Parquet (#23580)
  • Enum serialization assert (#23574)
  • Output type for peak_min / peak_max (#23573)
  • Make Scalar Categorical, Enum and Struct values serializable (#23565)
  • Preserve row order within partition when sinking parquet (#23462)
  • Prevent in-mem partition sink deadlock (#23562)
  • Update AWS cloud documentation (#23563)
  • Correctly handle null values when comparing structs (#23560)
  • Make fold/reduce/cum_reduce/cum_fold serializable (#23524)
  • Make Expr.append serializable (#23515)
  • Float by float division dtype (#23529)
  • Division on empty DataFrame generating null row (#23516)
  • Partition sink copy_exprs and with_exprs_and_input (#23511)
  • Unreachable with pl.self_dtype (#23507)
  • Rolling median incorrect min_samples with nulls (#23481)
  • Make Int128 roundtrippable via Parquet (#23494)
  • Fix panic when common subplans contain IEJoins (#23487)
  • Properly handle non-finite floats in rolling_sum/mean (#23482)
  • Make read_csv_batched respect skip_rows and skip_lines (#23484)
  • Always use cloudpickle for the python objects in cloud plans (#23474)
  • Support string literals in index_of() on categoricals (#23458)
  • Don't panic for finish_callback with nested datatypes (#23464)
  • Pass DeltaTable._storage_options if no storage_options are provided (#23456)
  • Support min/max aggregation for DataFrame/LazyFrame Categoricals (#23455)
  • Fix var/moment dtypes (#23453)
  • Fix agg_groups dtype (#23450)
  • Fix incorrect _get_path_scheme (#23444)
  • Fix missing overload defaults in read_ods and tree_format (#23442)
  • Clear cached_schema when apply changes dtype (#23439)
  • Allow structured conversion to/from numpy with Array types, preserving shape (#23438)
  • Null handling in full-null group_by_dynamic mean/sum (#23435)
  • Enable default set of ScanCastOptions for native scan_iceberg() (#23416)
  • Fix index calculation for nearest interpolation (#23418)
  • Overload for eager default in Schema.to_frame was False instead of True (#23413)
  • Fix read_excel overloads so that passing list[str] to sheet_name does not raise (#23388)
  • Removed special handling for bytes like objects in read_ndjson (#23361)
  • Parse parquet footer length into unsigned integer (#23357)
  • Fix incorrect results with group_by aggregation on empty groups (#23358)
  • Fix boolean min() in group_by aggregation (streaming) (#23344)
  • Respect data-model in map_elements (#23340)
  • Properly join URI paths in PlPath (#23350)
  • Ignore null values in bitwise aggregation on bools (#23324)
  • Fix panic filtering after left join (#23310)
  • Out-of-bounds index in hot hash table (#23311)
  • Fix scanning '?' from cloud with glob=False (#23304)
  • Fix filters on inserted columns did not remove rows (#23303)
  • Don't ignore return_dtype (#23309)
  • Raise error instead of return in Series class (#23301)
  • Use safe parsing for get_normal_components (#23284)
  • Fix output column names/order of streaming coalesced right-join (#23278)
  • Restore concat_arr inputs expansion (#23271)
  • Expose FieldsMapper (#23232)
  • Fix time zone handling in dt.iso_year and dt.is_leap_year (#23125)
📖 Documentation
  • Fix str.replace_many examples trigger deprecation warning (#23695)
  • Point the R Polars version on R-multiverse (#23660)
  • Update example for writing to cloud storage (#20265)
  • Update GPU docs for RAPIDS CUDA 11 deprecation (#23620)
  • Add docs of Expr.list.filter and Series.list.filter (#23589)
  • Add page about billing to Polars Cloud user guide (#23564)
  • Small user-guide improvement and fixes (#23549)
  • Correct note in from_pandas about data being cloned (#23552)
  • Fix a few typos in the "Streaming" section (#23536)
  • Update streaming page (#23535)
  • Update structure of Polars Cloud documentation (#23496)
  • Update example code in pandas migration guide (#23403)
  • Correct plugins user guide to reflect that teaching Expr.language is in a different section (#23377)
  • Add example of using OR in join_where (#23375)
  • Update when_then in user guide (#23245)
📦 Build system
  • Update all rand code (#23387)
🛠️ Other improvements
  • Add hashes json (#23758)
  • Add AExpr::is_expr_equal_to (#23740)
  • Fix rank test to respect maintain order (#23723)
  • IR inputs and exprs iterators (#23722)
  • Store more granular schema hashes to reduce merge conflicts (#23709)
  • Use UUID for UniqueID (#23704)
  • Remove scan id (#23697)
  • Propagate Iceberg physical ID schema to IR (#23671)
  • Remove unused and confusing match arm (#23691)
  • Remove unused ALLOW_GROUP_AWARE flag (#23690)
  • Remove unused evaluate_inline (#23687)
  • Remove unused field from AggregationContext (#23685)
  • Remove node_to_lp (#23678)
  • Fix cloud bytes scanning and read_* functions (#23642)
  • Group By maintain order on test (#23643)
  • Add maintain_order tests for streaming joins (#23577)
  • Continue on cloud testing (#23616)
  • Add pyo3-polars (#23571)
  • Remove _fetch (#23607)
  • Replace agg_list in AExpr::to_field with is_scalar_ae (#23582)
  • Mark select test case as write_disk (#23566)
  • Rolling order checking of test (#23568)
  • Multiple in-mem plans with reused cache #23561 (#23567)
  • Reduce warning in docs serve (#23534)
  • Remove left-behind print statement (#23533)
  • Make list.to_struct and arr.to_struct serializable (#23504)
  • Small conftest improvement (#23508)
  • Improve Categories error message (#23510)
  • Add test to ensure the global categories gets cleaned up (#23502)
  • Add more testing to group_by sorted test (#23500)
  • Pruning follow-up (#23501)
  • Make arg_min, arg_max, arg_sort and product into concrete DSL and IR constructs (#23493)
  • Simpify arena iterators (#23495)
  • Remove unnecessary may_fail_auto_streaming (#23477)
  • Remove StringCache from the test suite (#23473)
  • Make Selector a concrete part of the DSL (#23351)
  • Add streaming engine to code-coverage (#23441)
  • Remove hashbrown_nightly_hack (#23445)
  • Rework Categorical/Enum to use (Frozen)Categories (#23016)
  • Fix typing error from new pandas-stubs release (#23414)
  • Ignore Sort if 'by' is empty (#23320)
  • Rename from_buffer()/FromBuffer to reinterpret()/Reinterpret (#23362)
  • Only conver to ExprIR once in with_columns (#23352)
  • Update rust version in nix flake (#23347)
  • Update toolchain and fix clippy issues (#23334)
  • Improve cloud tests (#23312)
  • Casting from binview to primitives code moved from polars-ops to polars-compute (#23234)
  • Improve DSL source cache (#23282)
  • Add new PlPath that abstracts over PathBuf and URI (#23280)
  • Add may_fail_cloud mark for pytest (#23279)
  • Organize dsl_to_ir logic into modules (#23277)
  • Add flag for auto distributed testing (#23220)
  • Remove unused PyDataType (#23265)
  • Split FileScan in FileScanDsl and FileScanIR (#23260)
  • Update Rust Polars versions (#23239)
  • Connect Python assert_dataframe_equal() to Rust back-end (#23207)
  • Fix time zone handling in dt.iso_year and dt.is_leap_year (#23125)
  • Update Rust Polars versions (#23229)

Thank you to all our contributors for making this release possible! @Declow, @JakubValtar, @Kevin-Patyk, @Liyixin95, @MarcoGorelli, @Matt711, @TheLostLambda, @Washiil, @borchero, @c-peters, @cmdlineluser, @coastalwhite, @deanm0000, @eitsupi, @etiennebacher, @florian-klein, @gfvioli, @habaneraa, @itamarst, @kdn36, @ldhwaddell, @math-hiyoko, @mcrumiller, @mrkn, @nameexhaustion, @orlp, @othijssens, @r-brink, @ritchie46, @stijnherfst and @zyctree

View originalPermalink
How 1.32.0-beta.1 went
1.31.0

Python Polars 1.31.0

Added 10
  • Add DataType expressions in Python
  • Add native implementation for Iceberg positional deletes
  • Add `required: bool` to `ParquetFieldOverwrites`
  • Add `keys` column in `finish_callback`
  • Add `extra_columns` parameter to `scan_parquet`
  • Add CORR function to polars SQL
Changed 3
  • Support serializing `name.map_fields`
  • Support serializing `Expr::RenameAlias`
  • Derive DSL schema
Fixed 5
  • Remove axis in `show_graph`
  • Remove axis ticks in `show_graph`
  • Fix panic reading empty parquet with multiple boolean columns
  • Raise ComputeError instead of panicking in `truncate` when mixing month/week/day/sub-daily units
  • Materialize `list.eval` with unknown type
Removed 1
  • Remove old streaming engine
Deprecated 1
  • Deprecate `allow_missing_columns` in `scan_parquet` in favor of `missing_columns`
💥 Breaking changes
  • Remove old streaming engine (#23103)
⚠️ Deprecations
  • Deprecate allow_missing_columns in scan_parquet in favor of missing_columns (#22784)
🚀 Performance improvements
  • Improve streaming groupby CSE (#23092)
  • Move row index materialization in post-apply to occur after slicing (#22995)
  • Add first_(true|false)_idx to BooleanChunked and use in bool arg_(min|max) (#22907)
  • Don't go through row encoding for most types on index_of (#22903)
  • Optimise low-level null scans and arg_max for bools (when chunked) (#22897)
  • Optimize multiscan performance (#22886)
✨ Enhancements
  • DataType expressions in Python (#23167)
  • Native implementation for Iceberg positional deletes (#23091)
  • Remove old streaming engine (#23103)
  • Basic implementation of DataTypeExpr in Rust DSL (#23049)
  • Add required: bool to ParquetFieldOverwrites (#23013)
  • Support serializing name.map_fields (#22997)
  • Support serializing Expr::RenameAlias (#22988)
  • Remove duplicate verbose logging from FetchedCredentialsCache (#22973)
  • Add keys column in finish_callback (#22968)
  • Add extra_columns parameter to scan_parquet (#22699)
  • Add CORR function to polars SQL (#22690)
  • Add per partition sort and finish callback to sinks (#22789)
  • Support descendingly-sorted values in search_sorted() (#22825)
  • Derive DSL schema (#22866)
🐞 Bug fixes
  • Remove axis in show_graph (#23218)
  • Remove axis ticks in show_graph (#23210)
  • Restrict custom aggregate_function in pivot to pl.element() (#23155)
  • Don't leak SourceToken in in-memory sink linearize (#23201)
  • Fix panic reading empty parquet with multiple boolean columns (#23159)
  • Raise ComputeError instead of panicking in truncate when mixing month/week/day/sub-daily units (#23176)
  • Materialize list.eval with unknown type (#23186)
  • Only set sorting flag for 1st column with PQ SortingColumns (#23184)
  • Typo in AExprBuilder (#23171)
  • Null return from var/std on scalar column (#23158)
  • Support Datetime broadcast in list.concat (#23137)
  • Ensure projection pushdown maintains right table schema (#22603)
  • Add Null dtype support to arg_sort_by (#23107)
  • Raise error by default on invalid CSV quotes (#22876)
  • Fix group_by mean and median returning all nulls for Decimal dtype (#23093)
  • Fix hive partition pruning not filtering out __HIVE_DEFAULT_PARTITION__ (#23074)
  • Fix AssertionError when using scan_delta() on AWS with storage_options (#23076)
  • Fix deadlock on collect(background=True) / collect_concurrently() (#23075)
  • Incorrect null count in rolling_min/max (#23073)
  • Preserve file:// in LazyFrame node traverser (#23072)
  • Respect column order in register_io_source schema (#23057)
  • Don't call unnest for objects implementing __arrow_c_array__ (#23069)
  • Incorrect output when using sort with group_by and cum_sum (#23001)
  • Implement owned arithmetic for Int128 (#23055)
  • Do not schema-match structs with different field counts (#23018)
  • Fix confusing error message on duplicate row_index (#23043)
  • Add include_nulls to Agg::Count CSE check (#23032)
  • View buffer exceeding 2^32 - 1 bytes in concatenate_view (#23017)
  • Fix incorrect result selecting pl.len() from scan_csv with skip_lines (#22949)
  • Allow for IO plugins with reordered columns in streaming (#22987)
  • Method str.zfill was inconsistent with Python and pandas when string contained leading '+' (#22985)
  • Integer underflow in propagate_nulls (#22986)
  • Setting compat_level=0 for sink_ipc (#22960)
  • Narrow return type for DataType.is_, improve Pyright's type completeness from 69% to 95% (#22962)
  • Support arrow Decimal32 and Decimal64 types (#22954)
  • Guard against dictionaries being passed to projection keywords (#22928)
  • Update arrow format (#22941)
  • Fix filter pushdown to IO plugins (#22910)
  • Improve numeric stability rolling_mean<f32> (#22944)
  • Guard against invalid nested objects in 'map_elements' (#22932)
  • Allow subclasses in type equality checking (#22915)
  • Return early in pl.Expr.__array_ufunc__ when only single input (#22913)
  • Add inline implodes in type coercion (#22885)
  • Add {top, bottom}_k_by to Series (#22902)
  • Correct int_ranges to raise error on invalid inputs (#22894)
  • Don't silently overflow for temporal casts (#22901)
  • Fix error using write_csv with storage_options (#22881)
  • Schema resolution .over(mapping_strategy="join") with non-aggregations (#22875)
  • Ensure rename behaves the same as select (#22852)
📖 Documentation
  • Document aggregations that return identity when there's no non-null values, suggest workaround for those who want SQL-standard behaviour (#23143)
  • Fix reference to non-existent Expr.replace_all in replace_strict docs (#23144)
  • Fix typo on pandas comparison page (#23123)
  • Minor improvement to cum_count docstring example (#23099)
  • Add missing DataFrame.__setitem__ to API reference (#22938)
  • Add missing entry for LazyFrame __getitem__ (#22924)
  • Add missing top_k_by and bottom_k_by to Series reference (#22917)
📦 Build system
  • Update pyo3 and numpy crates to version 0.25 (#22763)
  • Actually disable ir_serde by default (#23046)
  • Add a feature flag for serde_ignored (#22957)
  • Fix warnings, update DSL version and schema hash (#22953)
🛠️ Other improvements
  • Change flake to use venv (#23219)
  • Add default_alloc feature to py-polars (#23202)
  • Added more descriptive error message by replacing FixedSizeList with Array (#23168)
  • Connect Python assert_series_equal() to Rust back-end (#23141)
  • Refactor skip_batches to use AExprBuilder (#23147)
  • Use ir_serde instead of serde for IRFunctionExpr (#23148)
  • Separate FunctionExpr and IRFunctionExpr (#23140)
  • Remove AExpr::Alias (#23070)
  • Add components for Iceberg deletion file support (#23059)
  • Feature gate StructFunction::JsonEncode (#23060)
  • Propagate iceberg position delete information to IR (#23045)
  • Add environment variable to get Parquet decoding metrics (#23052)
  • Turn pl.cumulative_eval into its own AExpr (#22994)
  • Add make test-streaming (#23044)
  • Move scan parameter parsing for parquet to reusable function (#23019)
  • Prepare deltalake 1.0 (#22931)
  • Implement Hash and use SpecialEq for RenameAliasFn (#22989)
  • Turn list.eval into an AExpr (#22911)
  • Fix CI for latest pandas-stubs release (#22971)
  • Add a CI check for DSL schema changes (#22898)
  • Add schema parameters to expr.meta (#22906)
  • Update rust toolchain in nix flake (#22905)
  • Update toolchain (#22859)

Thank you to all our contributors for making this release possible! @Athsus, @DahaoALG, @FabianWolff, @JakubValtar, @Kevin-Patyk, @MarcoGorelli, @SanjitBasker, @alexander-beedie, @bschoenmaeckers, @coastalwhite, @deanm0000, @dsprenkels, @eitsupi, @florian-klein, @i1oveMyse1f, @ion-elgreco, @itamarst, @kdn36, @kutal10, @mcrumiller, @mroeschke, @nameexhaustion, @nikaltipar, @orlp, @paskhaver, @ritchie46, @stijnherfst and @thomasfrederikhoeck

View originalPermalink
How 1.31.0 went
1.31.0-beta.1Pre-release

Python Polars 1.31.0-beta.1

Added 12
  • Add first_(true|false)_idx to BooleanChunked and use in bool arg_(min|max)
  • DataType expressions in Python
  • Native implementation for Iceberg positional deletes
  • Basic implementation of DataTypeExpr in Rust DSL
  • Add required: bool to ParquetFieldOverwrites
  • Support serializing name.map_fields
Changed 4
  • Move row index materialization in post-apply to occur after slicing
  • Don't go through row encoding for most types on index_of
  • Optimise low-level null scans and arg_max for bools when chunked
  • Support descendingly-sorted values in search_sorted()
Fixed 3
  • Fix panic reading empty parquet with multiple boolean columns
  • Raise ComputeError instead of panicking in truncate when mixing month/week/day/sub-daily units
  • Materialize list.eval with unknown type
Removed 1
  • Remove old streaming engine
Deprecated 1
  • Deprecate allow_missing_columns in scan_parquet in favor of missing_columns
💥 Breaking changes
  • Remove old streaming engine (#23103)
⚠️ Deprecations
  • Deprecate allow_missing_columns in scan_parquet in favor of missing_columns (#22784)
🚀 Performance improvements
  • Improve streaming groupby CSE (#23092)
  • Move row index materialization in post-apply to occur after slicing (#22995)
  • Add first_(true|false)_idx to BooleanChunked and use in bool arg_(min|max) (#22907)
  • Don't go through row encoding for most types on index_of (#22903)
  • Optimise low-level null scans and arg_max for bools (when chunked) (#22897)
  • Optimize multiscan performance (#22886)
✨ Enhancements
  • DataType expressions in Python (#23167)
  • Native implementation for Iceberg positional deletes (#23091)
  • Remove old streaming engine (#23103)
  • Basic implementation of DataTypeExpr in Rust DSL (#23049)
  • Add required: bool to ParquetFieldOverwrites (#23013)
  • Support serializing name.map_fields (#22997)
  • Support serializing Expr::RenameAlias (#22988)
  • Remove duplicate verbose logging from FetchedCredentialsCache (#22973)
  • Add keys column in finish_callback (#22968)
  • Add extra_columns parameter to scan_parquet (#22699)
  • Add CORR function to polars SQL (#22690)
  • Add per partition sort and finish callback to sinks (#22789)
  • Support descendingly-sorted values in search_sorted() (#22825)
  • Derive DSL schema (#22866)
🐞 Bug fixes
  • Fix panic reading empty parquet with multiple boolean columns (#23159)
  • Raise ComputeError instead of panicking in truncate when mixing month/week/day/sub-daily units (#23176)
  • Materialize list.eval with unknown type (#23186)
  • Only set sorting flag for 1st column with PQ SortingColumns (#23184)
  • Typo in AExprBuilder (#23171)
  • Null return from var/std on scalar column (#23158)
  • Support Datetime broadcast in list.concat (#23137)
  • Ensure projection pushdown maintains right table schema (#22603)
  • Add Null dtype support to arg_sort_by (#23107)
  • Raise error by default on invalid CSV quotes (#22876)
  • Fix group_by mean and median returning all nulls for Decimal dtype (#23093)
  • Fix hive partition pruning not filtering out __HIVE_DEFAULT_PARTITION__ (#23074)
  • Fix AssertionError when using scan_delta() on AWS with storage_options (#23076)
  • Fix deadlock on collect(background=True) / collect_concurrently() (#23075)
  • Incorrect null count in rolling_min/max (#23073)
  • Preserve file:// in LazyFrame node traverser (#23072)
  • Respect column order in register_io_source schema (#23057)
  • Don't call unnest for objects implementing __arrow_c_array__ (#23069)
  • Incorrect output when using sort with group_by and cum_sum (#23001)
  • Implement owned arithmetic for Int128 (#23055)
  • Do not schema-match structs with different field counts (#23018)
  • Fix confusing error message on duplicate row_index (#23043)
  • Add include_nulls to Agg::Count CSE check (#23032)
  • View buffer exceeding 2^32 - 1 bytes in concatenate_view (#23017)
  • Fix incorrect result selecting pl.len() from scan_csv with skip_lines (#22949)
  • Allow for IO plugins with reordered columns in streaming (#22987)
  • Method str.zfill was inconsistent with Python and pandas when string contained leading '+' (#22985)
  • Integer underflow in propagate_nulls (#22986)
  • Setting compat_level=0 for sink_ipc (#22960)
  • Narrow return type for DataType.is_, improve Pyright's type completeness from 69% to 95% (#22962)
  • Support arrow Decimal32 and Decimal64 types (#22954)
  • Guard against dictionaries being passed to projection keywords (#22928)
  • Update arrow format (#22941)
  • Fix filter pushdown to IO plugins (#22910)
  • Improve numeric stability rolling_mean<f32> (#22944)
  • Guard against invalid nested objects in 'map_elements' (#22932)
  • Allow subclasses in type equality checking (#22915)
  • Return early in pl.Expr.__array_ufunc__ when only single input (#22913)
  • Add inline implodes in type coercion (#22885)
  • Add {top, bottom}_k_by to Series (#22902)
  • Correct int_ranges to raise error on invalid inputs (#22894)
  • Don't silently overflow for temporal casts (#22901)
  • Fix error using write_csv with storage_options (#22881)
  • Schema resolution .over(mapping_strategy="join") with non-aggregations (#22875)
  • Ensure rename behaves the same as select (#22852)
📖 Documentation
  • Document aggregations that return identity when there's no non-null values, suggest workaround for those who want SQL-standard behaviour (#23143)
  • Fix reference to non-existent Expr.replace_all in replace_strict docs (#23144)
  • Fix typo on pandas comparison page (#23123)
  • Minor improvement to cum_count docstring example (#23099)
  • Add missing DataFrame.__setitem__ to API reference (#22938)
  • Add missing entry for LazyFrame __getitem__ (#22924)
  • Add missing top_k_by and bottom_k_by to Series reference (#22917)
📦 Build system
  • Update pyo3 and numpy crates to version 0.25 (#22763)
  • Actually disable ir_serde by default (#23046)
  • Add a feature flag for serde_ignored (#22957)
  • Fix warnings, update DSL version and schema hash (#22953)
🛠️ Other improvements
  • Added more descriptive error message by replacing FixedSizeList with Array (#23168)
  • Connect Python assert_series_equal() to Rust back-end (#23141)
  • Refactor skip_batches to use AExprBuilder (#23147)
  • Use ir_serde instead of serde for IRFunctionExpr (#23148)
  • Separate FunctionExpr and IRFunctionExpr (#23140)
  • Remove AExpr::Alias (#23070)
  • Add components for Iceberg deletion file support (#23059)
  • Feature gate StructFunction::JsonEncode (#23060)
  • Propagate iceberg position delete information to IR (#23045)
  • Add environment variable to get Parquet decoding metrics (#23052)
  • Turn pl.cumulative_eval into its own AExpr (#22994)
  • Add make test-streaming (#23044)
  • Move scan parameter parsing for parquet to reusable function (#23019)
  • Prepare deltalake 1.0 (#22931)
  • Implement Hash and use SpecialEq for RenameAliasFn (#22989)
  • Turn list.eval into an AExpr (#22911)
  • Fix CI for latest pandas-stubs release (#22971)
  • Add a CI check for DSL schema changes (#22898)
  • Add schema parameters to expr.meta (#22906)
  • Update rust toolchain in nix flake (#22905)
  • Update toolchain (#22859)

Thank you to all our contributors for making this release possible! @Athsus, @DahaoALG, @FabianWolff, @JakubValtar, @Kevin-Patyk, @MarcoGorelli, @SanjitBasker, @alexander-beedie, @bschoenmaeckers, @coastalwhite, @deanm0000, @dsprenkels, @eitsupi, @florian-klein, @i1oveMyse1f, @ion-elgreco, @itamarst, @kdn36, @kutal10, @mroeschke, @nameexhaustion, @nikaltipar, @orlp, @paskhaver, @ritchie46, @stijnherfst and @thomasfrederikhoeck

View originalPermalink
How 1.31.0-beta.1 went
1.30.0

Python Polars 1.30.0

Added 10
  • Implement `list.filter` method
  • Implement `LazyFrame.match_to_schema` method
  • Add `nulls_equal` flag to `list/arr.contains`
  • Add streaming cross-join node
  • Add elementwise execution mode for `list.eval`
  • Add options to write Parquet field metadata
Changed 9
  • Switch eligible casts to non-strict in optimizer
  • Allow predicate passing `set_sorted`
  • Increase default cross-file parallelism limit for new-streaming multiscan
  • Support optimised init from non-dict `Mapping` objects in `from_records` and frame/series constructors
  • Allow `.over` to be called without `partition_by`
  • Support binaryoffset in search sorted
Fixed 1
  • Fix RuntimeError when serializing the same DataFrame from multiple threads
🚀 Performance improvements
  • Switch eligible casts to non-strict in optimizer (#22850)
  • Allow predicate passing set_sorted (#22797)
  • Increase default cross-file parallelism limit for new-streaming multiscan (#22700)
  • Add elementwise execution mode for list.eval (#22715)
  • Support optimised init from non-dict Mapping objects in from_records and frame/series constructors (#22638)
  • Add streaming cross-join node (#22581)
  • Switch off maintain_order in group-by followed by sort (#22492)
✨ Enhancements
  • Load AWS endpoint_url using boto3 (#22851)
  • Implemented list.filter (#22749)
  • Support binaryoffset in search sorted (#22786)
  • Add nulls_equal flag to list/arr.contains (#22773)
  • Implement LazyFrame.match_to_schema (#22726)
  • Improved time-string parsing and inference (generally, and via the SQL interface) (#22606)
  • Allow for .over to be called without partition_by (#22712)
  • Support AnyValue translation from PyMapping values (#22722)
  • Support optimised init from non-dict Mapping objects in from_records and frame/series constructors (#22638)
  • Support inference of Int128 dtype from databases that support it (#22682)
  • Add options to write Parquet field metadata (#22652)
  • Add cast_options parameter to control type casting in scan_parquet (#22617)
  • Allow casting List<UInt8> to Binary (#22611)
  • Allow setting of regex size limit using POLARS_REGEX_SIZE_LIMIT (#22651)
  • Support use of literal values as "other" when evaluating Series.zip_with (#22632)
  • Allow to read and write custom file-level parquet metadata (#21806)
  • Support PEP702 @deprecated decorator behaviour (#22594)
  • Support grouping by pl.Array (#22575)
  • Preserve exception type and traceback for errors raised from Python (#22561)
  • Use fixed-width font in streaming phys plan graph (#22540)
🐞 Bug fixes
  • Fix RuntimeError when serializing the same DataFrame from multiple threads (#22844)
  • Fix map_elements predicate pushdown (#22833)
  • Fix reverse list type (#22832)
  • Don't require numpy for search_sorted (#22817)
  • Add type equality checking for relevant methods (#22802)
  • Invalid output for fill_null after when.then on structs (#22798)
  • Don't panic for cross join with misaligned chunking (#22799)
  • Panic on quantile over nulls in rolling window (#22792)
  • Respect BinaryOffset metadata (#22785)
  • Correct the output order of PartitionByKey and PartitionParted (#22778)
  • Fallback to non-strict casting for deprecated casts (#22760)
  • Clippy on new stable version (#22771)
  • Handle sliced out remainder for bitmaps (#22759)
  • Don't merge Enum categories on append (#22765)
  • Fix unnest() not working on empty struct columns (#22391)
  • Fix the default value type in Schema init (#22589)
  • Correct name in unnest error message (#22740)
  • Provide "schema" to DataFrame, even if empty JSON (#22739)
  • Properly account for nulls in the is_not_nan check made in drop_nans (#22707)
  • Incorrect result from SQL count(*) with partition by (#22728)
  • Fix deadlock joining scanned tables with low thread count (#22672)
  • Don't allow deserializing incompatible DSL (#22644)
  • Incorrect null dtype from binary ops in empty group_by (#22721)
  • Don't mark str.replace_many with Mapping as deprecated (#22697)
  • Gzip has maximum compression of 9, not 10 (#22685)
  • Fix predicate pushdown of fallible expressions (#22669)
  • Fix index out of bounds panic when scanning hugging face (#22661)
  • Panic on group_by with literal and empty rows (#22621)
  • Return input instead of panicking if empty subset in drop_nulls() and drop_nans() (#22469)
  • Bump argminmax to 0.6.3 (#22649)
  • DSL version deserialization endianness (#22642)
  • Allow Expr.round() to be called on integer dtypes (#22622)
  • Fix panic when filtering based on row index column in parquet (#22616)
  • WASM and PyOdide compile (#22613)
  • Resolve get() SchemaMismatch panic (#22350)
  • Panic in group_by_dynamic on single-row df with group_by (#22597)
  • Add new_streaming feature to polars crate (#22601)
  • Consistently use Unix epoch as origin for dt.truncate (except weekly buckets which start on Mondays) (#22592)
  • Fix interpolate on dtype Decimal (#22541)
  • CSV count rows skipped last line if file did not end with newline (#22577)
  • Make nested strict casting actually strict (#22497)
  • Make replace and replace_strict mapping use list literals (#22566)
  • Allow pivot on Time column (#22550)
  • Fix error when providing CSV schema with extra columns (#22544)
  • Panic on bitwise op between Series and Expr (#22527)
  • Multi-selector regex expansion (#22542)
📖 Documentation
  • Add pre-release policy (#22808)
  • Fix broken link to service account page in Polars Cloud docs (#22762)
  • Add match_to_schema to API reference (#22777)
  • Provide additional explanation and examples for the value_counts "normalize" parameter (#22756)
  • Rework documentation for drop/fill for nulls/nans (#22657)
  • Add documentation to new RoundMode parameter in round (#22555)
  • Add missing repeat_by to API reference, fixup list.get (#22698)
  • Fix non-rendering bullet points in scan_iceberg (#22694)
  • Improve insert_column docstring (description and examples) (#22551)
  • Improve join documentation (#22556)
📦 Build system
  • Fix building polars-lazy with certain features (#22846)
  • Add missing features (#22839)
  • Patch pyo3 to disable recompilation (#22796)
🛠️ Other improvements
  • Update Rust Polars versions (#22854)
  • Add basic smoke test for free-threaded python (#22481)
  • Update Polars Rust versions (#22834)
  • Fix nix build (#22809)
  • Fix flake.nix to work on macos (#22803)
  • Unused variables on release build (#22800)
  • Update cloud docs (#22624)
  • Fix unstable list.eval performance test (#22729)
  • Add proptest implementations for all Array types (#22711)
  • Dispatch .write_* to .lazy().sink_*(engine='in-memory') (#22582)
  • Move to all optimization flags to QueryOptFlags (#22680)
  • Add test for str.replace_many (#22615)
  • Stabilize sink_* (#22643)
  • Add proptest for row-encode (#22626)
  • Update rust version in nix flake (#22627)
  • Add a nix flake with a devShell and package (#22246)
  • Use a wrapper struct to store time zone (#22523)
  • Add proptest testing for for parquet decoding kernels (#22608)
  • Include equiprobable as valid quantile method (#22571)
  • Remove confusing error context calling .collect(_eager=True) (#22602)
  • Fix test_truncate_path test case (#22598)
  • Unify function flags into 1 bitset (#22573)
  • Display the operation behind in-memory-map (#22552)

Thank you to all our contributors for making this release possible! @IvanIsCoding, @JakubValtar, @Julian-J-S, @LucioFranco, @MarcoGorelli, @WH-2099, @alexander-beedie, @borchero, @bschoenmaeckers, @cmdlineluser, @coastalwhite, @etiennebacher, @florian-klein, @itamarst, @kdn36, @mcrumiller, @nameexhaustion, @nikaltipar, @orlp, @pavelzw, @r-brink, @ritchie46, @stijnherfst, @teotwaki, @timkpaine and @wence-

View originalPermalink
How 1.30.0 went
1.30.0-beta.1Pre-release

Python Polars 1.30.0-beta.1

Added 12
  • Add streaming cross-join node
  • Support binaryoffset in search sorted
  • Add nulls_equal flag to list/arr.contains
  • Implement LazyFrame.match_to_schema
  • Support AnyValue translation from PyMapping values
  • Support inference of Int128 dtype from databases that support it
Changed 8
  • Increase default cross-file parallelism limit for new-streaming multiscan
  • Add elementwise execution mode for list.eval
  • Support optimised init from non-dict Mapping objects in from_records and frame/series constructors
  • Switch off maintain_order in group-by followed by sort
  • Improve time-string parsing and inference generally and via the SQL interface
  • Allow for .over to be called without partition_by
  • Allow casting List<UInt8> to Binary
  • Support use of literal values as "other" when evaluating Series.zip_with
🚀 Performance improvements
  • Increase default cross-file parallelism limit for new-streaming multiscan (#22700)
  • Add elementwise execution mode for list.eval (#22715)
  • Support optimised init from non-dict Mapping objects in from_records and frame/series constructors (#22638)
  • Add streaming cross-join node (#22581)
  • Switch off maintain_order in group-by followed by sort (#22492)
✨ Enhancements
  • Support binaryoffset in search sorted (#22786)
  • Add nulls_equal flag to list/arr.contains (#22773)
  • Implement LazyFrame.match_to_schema (#22726)
  • Improved time-string parsing and inference (generally, and via the SQL interface) (#22606)
  • Allow for .over to be called without partition_by (#22712)
  • Support AnyValue translation from PyMapping values (#22722)
  • Support optimised init from non-dict Mapping objects in from_records and frame/series constructors (#22638)
  • Support inference of Int128 dtype from databases that support it (#22682)
  • Add options to write Parquet field metadata (#22652)
  • Add cast_options parameter to control type casting in scan_parquet (#22617)
  • Allow casting List<UInt8> to Binary (#22611)
  • Allow setting of regex size limit using POLARS_REGEX_SIZE_LIMIT (#22651)
  • Support use of literal values as "other" when evaluating Series.zip_with (#22632)
  • Allow to read and write custom file-level parquet metadata (#21806)
  • Support PEP702 @deprecated decorator behaviour (#22594)
  • Support grouping by pl.Array (#22575)
  • Preserve exception type and traceback for errors raised from Python (#22561)
  • Use fixed-width font in streaming phys plan graph (#22540)
🐞 Bug fixes
  • Respect BinaryOffset metadata (#22785)
  • Correct the output order of PartitionByKey and PartitionParted (#22778)
  • Fallback to non-strict casting for deprecated casts (#22760)
  • Clippy on new stable version (#22771)
  • Handle sliced out remainder for bitmaps (#22759)
  • Don't merge Enum categories on append (#22765)
  • Fix unnest() not working on empty struct columns (#22391)
  • Fix the default value type in Schema init (#22589)
  • Correct name in unnest error message (#22740)
  • Provide "schema" to DataFrame, even if empty JSON (#22739)
  • Properly account for nulls in the is_not_nan check made in drop_nans (#22707)
  • Incorrect result from SQL count(*) with partition by (#22728)
  • Fix deadlock joining scanned tables with low thread count (#22672)
  • Don't allow deserializing incompatible DSL (#22644)
  • Incorrect null dtype from binary ops in empty group_by (#22721)
  • Don't mark str.replace_many with Mapping as deprecated (#22697)
  • Gzip has maximum compression of 9, not 10 (#22685)
  • Fix predicate pushdown of fallible expressions (#22669)
  • Fix index out of bounds panic when scanning hugging face (#22661)
  • Panic on group_by with literal and empty rows (#22621)
  • Return input instead of panicking if empty subset in drop_nulls() and drop_nans() (#22469)
  • Bump argminmax to 0.6.3 (#22649)
  • DSL version deserialization endianness (#22642)
  • Allow Expr.round() to be called on integer dtypes (#22622)
  • Fix panic when filtering based on row index column in parquet (#22616)
  • WASM and PyOdide compile (#22613)
  • Resolve get() SchemaMismatch panic (#22350)
  • Panic in group_by_dynamic on single-row df with group_by (#22597)
  • Add new_streaming feature to polars crate (#22601)
  • Consistently use Unix epoch as origin for dt.truncate (except weekly buckets which start on Mondays) (#22592)
  • Fix interpolate on dtype Decimal (#22541)
  • CSV count rows skipped last line if file did not end with newline (#22577)
  • Make nested strict casting actually strict (#22497)
  • Make replace and replace_strict mapping use list literals (#22566)
  • Allow pivot on Time column (#22550)
  • Fix error when providing CSV schema with extra columns (#22544)
  • Panic on bitwise op between Series and Expr (#22527)
  • Multi-selector regex expansion (#22542)
📖 Documentation
  • Fix broken link to service account page in Polars Cloud docs (#22762)
  • Add match_to_schema to API reference (#22777)
  • Provide additional explanation and examples for the value_counts "normalize" parameter (#22756)
  • Rework documentation for drop/fill for nulls/nans (#22657)
  • Add documentation to new RoundMode parameter in round (#22555)
  • Add missing repeat_by to API reference, fixup list.get (#22698)
  • Fix non-rendering bullet points in scan_iceberg (#22694)
  • Improve insert_column docstring (description and examples) (#22551)
  • Improve join documentation (#22556)
🛠️ Other improvements
  • Update cloud docs (#22624)
  • Fix unstable list.eval performance test (#22729)
  • Add proptest implementations for all Array types (#22711)
  • Dispatch .write_* to .lazy().sink_*(engine='in-memory') (#22582)
  • Move to all optimization flags to QueryOptFlags (#22680)
  • Add test for str.replace_many (#22615)
  • Stabilize sink_* (#22643)
  • Add proptest for row-encode (#22626)
  • Update rust version in nix flake (#22627)
  • Add a nix flake with a devShell and package (#22246)
  • Use a wrapper struct to store time zone (#22523)
  • Add proptest testing for for parquet decoding kernels (#22608)
  • Include equiprobable as valid quantile method (#22571)
  • Remove confusing error context calling .collect(_eager=True) (#22602)
  • Fix test_truncate_path test case (#22598)
  • Unify function flags into 1 bitset (#22573)
  • Display the operation behind in-memory-map (#22552)

Thank you to all our contributors for making this release possible! @JakubValtar, @Julian-J-S, @MarcoGorelli, @WH-2099, @alexander-beedie, @borchero, @cmdlineluser, @coastalwhite, @etiennebacher, @florian-klein, @itamarst, @kdn36, @mcrumiller, @nameexhaustion, @nikaltipar, @orlp, @pavelzw, @r-brink, @ritchie46, @stijnherfst, @teotwaki, @timkpaine and @wence-

View originalPermalink
How 1.30.0-beta.1 went
1.29.0

Python Polars 1.29.0

Added 7
  • Highlight nodes in streaming phys plan graph
  • Show physical stage graph
  • Add structure for dispatching iceberg to native scans
  • Add SQL support for checking array values with IN and NOT IN expressions
  • Support DataFrame and Series init from torch Tensor objects
  • Add RoundMode for Decimal and Float
  • Inform users that IO error path file name can be expanded with POLARS_VERBOSE=1
Changed 1
  • Avoid alloc_zeroed in decompression
Fixed 12
  • Fix streaming outer join coalesce bug
  • Remove redundant print statement in assert_frame_schema_equal()
  • Fix bug in .unique() followed by .slice()
  • Fix error reading parquet with datetimes written by pandas
  • Fix schema_overrides not taking effect in NDJSON
  • Fix fold flags and verify scalar correctness in apply
🚀 Performance improvements
  • Avoid alloc_zeroed in decompression (#22460)
✨ Enhancements
  • Highlight nodes in streaming phys plan graph (#22535)
  • Show physical stage graph (#22491)
  • Add structure for dispatching iceberg to native scans (#22405)
  • Add SQL support for checking array values with IN and NOT IN expressions (#22487)
  • Support DataFrame and Series init from torch Tensor objects (#22177)
  • Add RoundMode for Decimal and Float (#22248)
  • Inform users that IO error path file name can be expanded with POLARS_VERBOSE=1 (#22427)
🐞 Bug fixes
  • Streaming outer join coalesce bug (#22530)
  • Remove redundant print statement in assert_frame_schema_equal() (#22529)
  • Bug in .unique() followed by .slice() (#22471)
  • Fix error reading parquet with datetimes written by pandas (#22524)
  • Fix schema_overrides not taking effect in NDJSON (#22521)
  • Fold flags and verify scalar correctness in apply (#22519)
  • Invalid values were triggering panics instead of returning null in dt.to_date / dt.to_datetime (#22500)
  • Ensure numpy isinstance check is lazy (avoid forcing the dependency) (#22486)
  • Incorrectly dropped sort after unique for some queries (#22489)
  • Fix incorrect ternary agg state with mixed columns and scalars (#22496)
  • Make replace and replace_strict properly elementwise (#22465)
  • Fix index out of bounds panic on parquet prefiltering (#22458)
  • Integer underflow when checking parquet UTF-8 (#22472)
  • Add implementation for array.get with idx overflow (#22449)
  • Deprecate str. collection functions with flat strings and mark as elementwise (#22461)
  • Deprecate flat list.gather and mark as elementwise (#22456)
  • Inform users that IO error path file name can be expanded with POLARS_VERBOSE=1 (#22427)
📖 Documentation
  • Fix typo in structs page (#22504)
🛠️ Other improvements
  • Don't store name/dtype in grouper (#22525)
  • Add structure for dispatching iceberg to native scans (#22405)
  • Remove unused reduction code (#22462)
  • Pin to explicit macOS version in code coverage (#22432)

Thank you to all our contributors for making this release possible! @AH-Merii, @JakubValtar, @Julian-J-S, @Kevin-Patyk, @Liyixin95, @MarcoGorelli, @Matt711, @alexander-beedie, @brianmakesthings, @coastalwhite, @nameexhaustion, @orlp and @ritchie46

View originalPermalink
How 1.29.0 went
1.28.1

Python Polars 1.28.1

Changed 1
  • Update pyo3 and numpy crates to version 0.24
Fixed 2
  • Reading of reencoded categorical in Parquet
  • Last thread in parquet predicate filter out of bounds
🐞 Bug fixes
  • Reading of reencoded categorical in Parquet (#22436)
  • Last thread in parquet predicate filter oob (#22429)
📖 Documentation
  • Fix a few typos in the new "multiplexing" page (#22434)
  • Add multiplexing page (#22426)
📦 Build system
  • Update pyo3 and numpy crates to version 0.24 (#22015)
🛠️ Other improvements
  • Add test for implode + over (#22437)
  • Fix CI by removing use_legacy_dataset (#22438)
  • Only use pytorch index-url for pytorch package (#22355)

Thank you to all our contributors for making this release possible! @bschoenmaeckers, @coastalwhite, @etiennebacher, @mcrumiller and @ritchie46

View originalPermalink
How 1.28.1 went
1.28.0

Python Polars 1.28.0

Added 9
  • Add single-key variants of streaming group_by
  • Add dedicated rolling_skew kernel
  • Add Series backward_fill / forward_fill
  • Add GPU support to sink_* APIs
  • Add rolling_kurtosis
  • Support Cast in IO plugin predicates
Changed 10
  • Lower Expr.(n_)unique to group_by on streaming engine
  • Chunk huge munmap calls
  • Improve accumulate_dataframes_vertical performance
  • Optimize rolling_quantile with varying window sizes
  • Call large munmap's in background thread
  • New streaming group_by implementation
Fixed 2
  • Ensure write_excel correctly preserves null values in nested dtype data on export
  • Panic when visualizing streaming physical plan with joins
🚀 Performance improvements
  • Lower Expr.(n_)unique to group_by on streaming engine (#22420)
  • Chunk huge munmap calls (#22414)
  • Add single-key variants of streaming group_by (#22409)
  • Improve accumulate_dataframes_vertical performance (#22399)
  • Use optimize rolling_quantile with varying window sizes (#22353)
  • Dedicated rolling_skew kernel (#22333)
  • Call large munmap's in background thread (#22329)
  • New streaming group_by implementation (#22285)
  • Patch jemalloc to not purge huge allocs eagerly if we have background threads (#22318)
  • Turn on parallel=prefiltered by default for new streaming (#22190)
✨ Enhancements
  • When reporting unexpected types in errors, module-qualify the typename (#22390)
  • Add Series backward_fill / forward_fill (#22360)
  • Add GPU support to sink_* APIs (#20940)
  • Changed mapping type from dict to Mapping (#19400) (#19436)
  • Make streaming dispatch public (#22347)
  • Add rolling_kurtosis (#22335)
  • Support Cast in IO plugin predicates (#22317)
  • Add .sort(nulls_last=True) to booleans, categoricals and enums (#22300)
  • Add rolling min/max for temporals (#22271)
  • Support literal:list agg (#22249)
  • Support running Polars SQL queries against any objects implementing the PyCapsule interface (#22235)
  • Support implode + agg (#22230)
  • Dispatch scans to new-streaming by default (#22153)
🐞 Bug fixes
  • Ensure write_excel correctly preserves null values in nested dtype data on export (#22379)
  • Panic when visualizing streaming physical plan with joins (#22404)
  • Fix incorrect filter after LazyFrame.rename().select() (#22380)
  • Fix select(len()) performance regression (#22363)
  • Handle pytz named timezone in lit (#21785)
  • Don't leak state during prefill CSE cache (#22341)
  • Maintain float32 type in partitioned group-by (#22340)
  • Resolve streaming panic on multiple merge_sorted (#22205)
  • Fix ndjson nested types (#22325)
  • Fix nested datetypes in ndjson (#22321)
  • Check matching lengths for pl.corr (#22305)
  • Move type coercion for pl.duration to planner (#22304)
  • Check dtype to avoid panic with mixed types in min/max_horizontal (#21857)
  • Coalesce correct column for new streaming full join (#22301)
  • Don't collect NaN from Parquet Statistics (#22294)
  • Set revmap for empty AnyValue to Series (#22293)
  • Add an __all__ entry to internal type definition module (#22254)
  • Datetime parser was incorrectly parsing 8-digit fractional seconds when format specified to expect 9 (#22180)
  • More robust str → date conversion when reading from spreadsheet (#22276)
  • Deprecate using is_in with 2 equal types and mark as elementwise (#22178)
  • Duplicate key column name in streaming group_by due to CSE (#22280)
  • Raise ColumnNotFoundError for missing columns in join_where (#22268)
  • Parquet filters for logical types and operations (#22253)
  • Ensure floating-point accuracy in hist (#22245)
  • Check matching key datatypes for new streaming joins (#22247)
  • Incorrect length BinaryArray/ListBuilder (#22227)
📖 Documentation
  • Update docs for schema arg in scan_csv to match read_csv (#22357)
  • Update pl.when documentation (#22345)
  • Add missing is_business_day to documentation reference (#22338)
  • Improve interpolation documentation to clarify behavior of null values (#22274)
🛠️ Other improvements
  • Install pytorch for 3.13 on Windows (#22356)
  • Make interpolate fix more robust (#22421)
  • Fix interpolate test (#22417)
  • Reduce hot table size in debug mode (#22400)
  • Replace intrinsic with non-intrinsic (#22401)
  • Make streaming dispatch public (#22347)
  • Update rustc to 'nightly-2025-04-19' (#22342)
  • Update mozilla-actions/sccache-action (#22319)
  • Purge old parquet and scan code (#22226)
  • Add an __all__ entry to internal type definition module (#22254)
  • Add online skew/kurtosis algorithm for future use in rolling kernels (#22261)
  • Add Polars Cloud 0.0.7 release notes (#22223)
  • Change format name from list to implode (#22240)
  • Make other parallel parquet modes filter afterwards (#22228)
  • Close async reader issues (#22224)
  • Add BinaryArrayBuilder (#22225)

Thank you to all our contributors for making this release possible! @DavideCanton, @JakubValtar, @Jesse-Bakker, @MarcoGorelli, @NeejWeej, @Shoeboxam, @adamreeve, @alexander-beedie, @axellpadilla, @cmdlineluser, @coastalwhite, @d-reynol, @dongchao-1, @florian-klein, @kdn36, @math-hiyoko, @mcrumiller, @mroeschke, @nameexhaustion, @orlp, @ritchie46, @stijnherfst and @yiteng-guo

View originalPermalink
How 1.28.0 went
1.27.1

Python Polars 1.27.1

Changed 1
  • Improved expression autocomplete for IPython, Jupyter, and Marimo
Fixed 5
  • Incorrect condition on empty inner join fast path
  • Fallback predicate filter for min=max with is_in
  • Don't panic for LruCachedFunc for size=0
  • Writing masked out list values to json
  • Deadlock in streaming distributor
✨ Enhancements
  • Improved expression autocomplete for IPython, Jupyter, and Marimo (#22221)
🐞 Bug fixes
  • Incorrect condition on empty inner join fast path (#22208)
  • Fallback predicate filter for min=max with is_in (#22213)
  • Don't panic for LruCachedFunc for size=0 (#22215)
  • Writing masked out list values to json (#22210)
  • Deadlock in streaming distributor (#22207)

Thank you to all our contributors for making this release possible! @Matt711, @alexander-beedie, @coastalwhite, @dependabot[bot], @orlp, @ritchie46 and dependabot[bot]

View originalPermalink
How 1.27.1 went
1.27.0

Python Polars 1.27.0

Added 11
  • Add SPLIT_PART string function to the SQL interface
  • Support additional unsigned int aliases in the SQL interface
  • Add STRING_TO_ARRAY function to the SQL interface
  • Add dt.is_business_day
  • Add an eager parameter to pl.cov
  • Add support for Int128 parsing and recognition to the SQL interface
Changed 6
  • Make bottom interval closed in hist
  • Change Partition API to base_path and file_path
  • Allow scalar expr in Expr.diff
  • Support growing schema if line length increases during csv schema inference
  • Replace thread unsafe GilOnceCell with Mutex
  • Support modified dsl in file cache
Fixed 1
  • Implode in agg
Deprecated 1
  • Deprecate duplicate backward_fill and forward_fill interface
💥 Breaking changes
  • Make bottom interval closed in hist (#22090)
  • Change Partition API to base_path and file_path (#21888)
🚀 Performance improvements
  • Add CSE to streaming groupby (#22196)
  • Speed-up new streaming predicate filtering (#22179)
  • Speedup new-streaming file row count (#22169)
  • Fix quadratic behavior when casting Enums (#22008)
  • Lower is_in to bitmap-output semi-join in new streaming engine (#21948)
  • Fast path for empty inner join (#21965)
  • Add native semi/anti join in new streaming engine (#21937)
  • Cache regex compilation globally (#21929)
✨ Enhancements
  • Add SPLIT_PART string function to the SQL interface (#22158)
  • Allow scalar expr in Expr.diff (#22142)
  • Support additional unsigned int aliases in the SQL interface (#22127)
  • Add STRING_TO_ARRAY function to the SQL interface (#22129)
  • Add dt.is_business_day (#21776)
  • Add an eager parameter to pl.cov (#22098)
  • Add support for Int128 parsing/recognition to the SQL interface (#22104)
  • Add an eager parameter to pl.coalesce (#22092)
  • Add an eager parameter to pl.corr (#22097)
  • Allow sinking to abstract python io and fs classes (#21987)
  • Add add_alp_optimize_exprs to IRBuilder (#22061)
  • Add cat.slice (#21971)
  • Support growing schema if line lenght increases during csv schema inference (#21979)
  • Replace thread unsafe GilOnceCell with Mutex (#21927)
  • Support modified dsl in file cache (#21907)
🐞 Bug fixes
  • Implode in agg (#22197)
  • Reduce GIL hold time for IO plugins in new-streaming (#22186)
  • Enhance predicate validation and cast safety in join_where (#22112)
  • Handle Parquet with compressed empty DataPage v2 (#22172)
  • Schema error during lowering (#22175)
  • Rewrite unroll of overlapping groups to mitigate out of range index panic (#22072)
  • Incorrect rounding for very large/small numbers (#22173)
  • Allow set input to list.set_* operations (#22163)
  • Deadlock in join due to rayon nested task-stealing (#22159)
  • Mark Expr.repeat_by as elementwise (#22068)
  • Fix csv serializer panic by supporting ScalarColumn in as_single_chunk (#22146)
  • Raise an error if a number doesn't have associated unit in duration strings (#22035)
  • Add i128 as supertype to boolean (#22138)
  • Fix panic when constructing DF from pyarrow due to duplicate field names (#22114)
  • Add broadcasts and error messages for many elementwise operations (#22130)
  • Throw error for n=0 on list.gather_every (#22122)
  • Throw error for unsupported rolling operations (#22121)
  • Error on unequal length str.to_integer arguments (#22100)
  • Make bottom interval closed in hist (#22090)
  • Relative path resolution for plugin libraries (#21911)
  • Avoiding panic with striptime for out-of-bounds dates (#21208)
  • Join revmaps for categoricals in merge_sorted (#21976)
  • Fix glob expansion matching extra files (#21991)
  • Ensure SQL dot-notation for nested column fields resolves correctly (#22109)
  • Parquet filter performance regression from multiscan dispatch (#22116)
  • Panic for unequal length ewm_mean_by args (#22093)
  • Add scalarity checks to pl.repeat (#22088)
  • Type check n parameter of pl.repeat (#22071)
  • Mark bitwise_{count,leading,trailing}_{ones,zeros} as elementwise (#22044)
  • Mark pl.*_ranges functions correctly as element-wise (#22059)
  • Correctly type check pl.arctan2 (#22060)
  • Mark pl.business_day_count as elementwise (#22055)
  • Check input python type for str.extract_groups (#22032)
  • Check types for fill_char in str.pad_{start,end} (#22036)
  • Mark str.to_decimal properly as non-elementwise (#22040)
  • Documented return type for bin.encode and bin.decode (#22022)
  • Revert #22017 and improve block(_in_place)_on doc comment (#22031)
  • Remove outdated depth warning (#22030)
  • Expression pl.concat was incorrectly marked as elementwise (#22019)
  • Use block_in_place_on to start streaming (#22017)
  • Panic on empty aggregation in streaming (#22016)
  • Error instead of panick for invalid durations in dt.offset_by() and dt.round() (#21982)
  • Raise error instead of silently appending NULL in NDJSON parsing (#21953)
  • Ensure AV is static before pushing to row buffer (#21967)
  • Deadlock in new-streaming multiplexer (#21963)
  • Release GIL in collect_with_callback (#21941)
  • Panic in new RegexCache (#21935)
  • Type hint of cs.exclude() is SelectorType instead of Expr (#21892)
  • Add correct deprecation warning for .str.concat (#21666)
  • Use absolute paths by defaults for plugins (#21904)
📖 Documentation
  • Add user guide section on working with Sheets in Colab (#22161)
  • Update distributed engine docs (#22128)
  • Add Polars Cloud release notes (#22021)
  • Remove trailing space in settings POLARS_CLOUD_CLIENT_ID (#21995)
  • Fix typo (#21954)
  • Fix 'pickleable' typo in docs (#21938)
  • Change ctx to compute=ctx for all remote query examples (#21930)
🛠️ Other improvements
  • Remove old MultiScanExec for in-memory (#22184)
  • Separate FunctionOptions from DSL calls (#22133)
  • Undeprecate backward_fill and forward_fill (#22156)
  • Handle conversion of Duration specially in pyir (#22101)
  • Deprecate duplicate backward_fill and forward_fill interface (#22083)
  • Solve clippy lints for 1.86 (#22102)
  • Remove rust exclusive MaxBound and MinBound fill strategies (#22063)
  • Change Partition API to base_path and file_path (#21888)
  • Fix pydantic model_fields deprecation (#21958)

Thank you to all our contributors for making this release possible! @DeflateAwning, @EnricoMi, @Jacob640, @JakubValtar, @MarcoGorelli, @MaxJackson, @alexander-beedie, @amotzop, @anath2, @bschoenmaeckers, @cnpryer, @coastalwhite, @dependabot[bot], @eitsupi, @etiennebacher, @hemanth94, @kdn36, @mcrumiller, @nameexhaustion, @orlp, @r-brink, @rgertenbach, @ritchie46, @sebasv, @silannisik, @stijnherfst, @wence-, @zachlefevre and dependabot[bot]

View originalPermalink
How 1.27.0 went
1.26.0

Python Polars 1.26.0

Added 4
  • Add support for io-plugins in new-streaming
  • Add PartitionParted
  • Add explain_all
  • Add option to use relative paths for plugin libraries
Changed 9
  • Use views for binary hash tables and add single-key binary variant
  • Avoid rechunking in gather
  • Switch ahash for foldhash
  • Put THP behind feature flag
  • Enable THP by default
  • Improve join performance for expanding joins
Fixed 7
  • Fix DataFrame.nan_to_null work for tuple
  • Allow pivot on empty frame for all integer index dtypes
  • Fix null panic on decimal aggregate
  • Fix join with categoricals on new-streaming engine
  • Fix div 0 partitioned group-by
  • Fix incorrect quote check in CSV parser
  • Respect header separator in sink_csv
🚀 Performance improvements
  • Use views for binary hash tables and add single-key binary variant (#21872)
  • Avoid rechunking in gather (#21876)
  • Switch ahash for foldhash (#21852)
  • Put THP behind feature flag (#21853)
  • Enable THP by default (#21829)
  • Improve join performance for expanding joins (#21821)
  • Use binary_search instead of contains in business-day functions (#21775)
✨ Enhancements
  • Add support for io-plugins in new-streaming (#21870)
  • Add PartitionParted (#21788)
  • Minor improvements to EXPLAIN plan output (#21822)
  • Add explain_all (#21797)
  • Allow to use repeat_by with (nested) lists and structs (#21206)
🐞 Bug fixes
  • Fix DataFrame.nan_to_null work for tuple (#21861)
  • Allow pivot on empty frame for all integer index dtypes (#21890)
  • Null panic on decimal aggregate (#21873)
  • Join with categoricals on new-streaming engine (#21825)
  • Fix div 0 partitioned group-by (#21842)
  • Incorrect quote check in CSV parser (#21826)
  • Add option to use relative paths for plugin libraries (#21675)
  • Respect header separator in sink_csv (#21814)
  • Deprecation of streaming=False (#21813)
  • Fix collect_all type-coercion (#21810)
  • Memory leaks in SharedStorage (#21798)
  • Make None refer to uncompressed in sink_ipc (#21786)
📖 Documentation
  • Add sources and sinks to user-guide (#21780)
🛠️ Other improvements
  • Change dynamic literals to be separate category (#21849)
  • Add POLARS_TIMEOUT_MS for timing out slow Polars tests (#21887)
  • Disable --dist loadgroup in pytest (#21885)
  • Fix refcount assert being messed up by pytest assertion magic (#21884)
  • Add env vars to configure new-streaming buffer sizes (#21818)

Thank you to all our contributors for making this release possible! @Kevin-Patyk, @MarcoGorelli, @alexander-beedie, @anath2, @borchero, @coastalwhite, @dongchao-cn, @kgv, @mcrumiller, @nameexhaustion, @orlp and @ritchie46

View originalPermalink
How 1.26.0 went
1.25.2

Python Polars 1.25.2

Added 6
  • Add lazy sinks
  • Add PartitionByKey for new streaming sinks
  • Add a config option to specify the default engine to attempt to use during lazyframe calls
  • Add len method to arr
  • Add new PartitionMaxSize sink
  • Add NDJSON source to new streaming engine
Changed 9
  • Enable common subplan elimination across plans in collect_all
  • Implement linear-time rolling_min/max
  • Improve InputIndependentSelect by delegating to InMemorySourceNode
  • Add support for rolling_(sum/min/max) for booleans through casting
  • Support multi-column sort for all nested types and nested search-sorted
  • Enable joins on list/array dtypes
Fixed 5
  • Fix lazy schema for truediv ops involving List/Array dtypes
  • Fix error due to race condition in file cache
  • Clear NaNs due to zero-weight division in rolling var/std
  • New streaming multiscan deadlock
  • Fix deadlock in cache + hconcat
🏆 Highlights
  • Enable common subplan elimination across plans in collect_all (#21747)
  • Add lazy sinks (#21733)
  • Add PartitionByKey for new streaming sinks (#21689)
  • Enable new streaming memory sinks by default (#21589)
🚀 Performance improvements
  • Implement linear-time rolling_min/max (#21770)
  • Improve InputIndependentSelect by delegating to InMemorySourceNode (#21767)
  • Enable common subplan elimination across plans in collect_all (#21747)
  • Allow elementwise functions in recursive lowering (#21653)
  • Add primitive single-key hashtable to new-streaming join (#21712)
  • Remove unnecessary black_boxes in Kahan summation (#21679)
  • Box large enum variants (#21657)
  • Improve join performance for new-streaming engine (#21620)
  • Pre-fill caches (#21646)
  • Optimize only a single cache input (#21644)
  • Collect parquet statistics in one contiguous buffer (#21632)
  • Update Cargo.lock (mainly for zstd 1.5.7) (#21612)
  • Don't maintain order when maintain_order=False in new streaming sinks (#21586)
  • Pre-sort groups in group-by-dynamic (#21569)
✨ Enhancements
  • Add support for rolling_(sum/min/max) for booleans through casting (#21748)
  • Support multi-column sort for all nested types and nested search-sorted (#21743)
  • Add lazy sinks (#21733)
  • Add PartitionByKey for new streaming sinks (#21689)
  • Fix replace flags (#21731)
  • Add mkdir flag to sinks (#21717)
  • Enable joins on list/array dtypes (#21687)
  • Add a config option to specify the default engine to attempt to use during lazyframe calls (#20717)
  • Support all elementwise functions in IO plugin predicates (#21705)
  • Stabilize Enum datatype (#21686)
  • Support Polars int128 in from arrow (#21688)
  • Use FFI to read dataframe instead of transmute (#21673)
  • Enable new streaming memory sinks by default (#21589)
  • Cloud support for new-streaming scans and sinks (#21621)
  • Add len method to arr (#21618)
  • Closeable files on unix (#21588)
  • Add new PartitionMaxSize sink (#21573)
  • Support engine callback for LazyFrame.profile (#21534)
  • Dispatch new-streaming CSV negative slice to separate node (#21579)
  • Add NDJSON source to new streaming engine (#21562)
  • Support passing token in storage_options for GCP cloud (#21560)
🐞 Bug fixes
  • Expose and document partitions (#21765)
  • Fix lazy schema for truediv ops involving List/Array dtypes (#21764)
  • Fix error due to race condition in file cache (#21753)
  • Clear NaNs due to zero-weight division in rolling var/std (#21761)
  • Allow init from BigQuery Arrow data containing ExtensionType cols with irrelevant metadata (#21492)
  • Disallow cast from boolean to categorical/enum (#21714)
  • Don't check sortedness in join_asof when 'by' groups supplied, but issue warning (#21724)
  • Incorrect multithread path taken for aggregations (#21727)
  • Disallow cast to empty Enum (#21715)
  • Fix list.mean and list.median returning Float64 for temporal types (#21144)
  • Incorrect (FixedSize)ListArrayBuilder gather implementation (#21716)
  • Always fallback in SkipBatchPredicate (#21711)
  • New streaming multiscan deadlock (#21694)
  • Ensure new-streaming join BuildState is correct even if never fed morsels (#21708)
  • IO plugin; support empty iterator (#21704)
  • Support nulls in multi-column sort (#21702)
  • Window function check length of groups state (#21697)
  • Support 128 sum reduction on new streaming (#21691)
  • IPC round-trip of list of empty view with non-empty bufferset (#21671)
  • Variance can never be negative (#21678)
  • Incorrect loop length in new-streaming group by (#21670)
  • Right join on multiple columns not coalescing left_on columns (#21669)
  • Casting Struct to String panics if n_chunks > 1 (#21656)
  • FixFuture attached to different loop error on read_database_uri (#21641)
  • Fix deadlock in cache + hconcat (#21640)
  • Properly handle phase transitions in row-wise sinks (#21600)
  • Enable new streaming memory sinks by default (#21589)
  • Always use global registry for object (#21622)
  • Check enum categories when reading csv (#21619)
  • Unspecialized prefiltering on nullable arrays (#21611)
  • Release the gil on explain (#21607)
  • Take into account scalar/partitioned columns in DataFrame::split_chunks (#21606)
  • Bad null handling in unordered row encoding (#21603)
  • Fix deadlock in new streaming CSV / NDJSON sinks (#21598)
  • Bad view index in BinaryViewBuilder (#21590)
  • Fix CSV count with comment prefix skipped empty lines (#21577)
  • New streaming IPC enum scan (#21570)
  • Several aspects related to ParquetColumnExpr (#21563)
  • Don't hit parquet::pre-filtered in case of pre-slice (#21565)
📖 Documentation
  • Add skrub to ecosystem.md (#21760)
  • Add example for percentile rank (#21746)
  • Make python/rust getting-started consistent and clarify performance risk of infer_schema_length=None (#21734)
  • Add expression composability to PySpark comparison (#21473)
  • Document read_().lazy() antipattern (#21623)
  • Update Polars Cloud interactive workflow examples (#21609)
  • Add a Plotnine example to the visualization docs (#21597)
  • Add cloud api reference to Ref guide (#21566)
🛠️ Other improvements
  • Remove variance numerical stability hack (#21749)
  • Only use chrono_tz timezones in hypothesis testing (#21721)
  • Remove order check from flaky test (#21730)
  • Add sinks into the DSL before optimization (#21713)
  • Add missing test case for #21701 (#21709)
  • Remove old-streaming from engine argument (#21667)
  • Add as_phys_any to PrivateSeries for downcasting (#21696)
  • Use FFI to read dataframe instead of transmute (#21673)
  • Work around typos ignore bug (#21672)
  • Added Test For datetime_range Nanosecond Overflow (#21354)
  • Update to edition 2024 (#21662)
  • Update rustc (#21647)
  • Support object from chunks (#21636)
  • Push versioned docs on workflow dispatch (#21630)
  • Fail docs early (#21629)
  • Check major/minor in docs (#21626)
  • Add docs workflow (#21624)
  • Add test for 21581 (#21617)
  • Remove even more parquet multiscan handling (#21601)
  • Remove multiscan handling from new streaming parquet source (#21584)
  • Prepare skeleton for partitioning sinks (#21536)

Thank you to all our contributors for making this release possible! @GaelVaroquaux, @Kevin-Patyk, @MarcoGorelli, @Matt711, @NathanHu725, @alexander-beedie, @coastalwhite, @dependabot[bot], @jrycw, @kdn36, @lukemanley, @mcrumiller, @nameexhaustion, @orlp, @r-brink, @ritchie46, @wence- and dependabot[bot]

View originalPermalink
How 1.25.2 went
1.24.0

Python Polars 1.24.0

Added 5
  • Add lossy decoding to read_csv for non-utf8 encodings
  • Add DataFrame.write_iceberg
  • Add nulls_equal parameter to is_in
  • Support writing Time type in json
  • Add AssertionError variant to PolarsError in polars-error
Changed 4
  • Improve numeric stability in rolling_std, rolling_var, rolling_cov, rolling_corr
  • Rename join_nulls parameter to nulls_equal in join functions
  • Move rolling to polars-compute
  • Use tikv-jemallocator
Fixed 11
  • Categorical min/max panicking when string cache is enabled
  • Don't encode IPC record batch twice
  • Respect rewriting flag in Node rewriter
  • Correct skip batch predicate for partial statistics
  • Make the Parquet Sink properly phase aware
  • Don't divide by zero in partitioned group-by
🚀 Performance improvements
  • Provide a fallback skip batch predicate for constant batches (#21477)
  • Parallelize the passing in new streaming multiscan (#21430)
✨ Enhancements
  • Add lossy decoding to read_csv for non-utf8 encodings (#21433)
  • Add DataFrame.write_iceberg (#15018)
  • Add 'nulls_equal' parameter to is_in (#21426)
  • Improve numeric stability rolling_{std, var, cov, corr} (#21528)
  • IR Serde cross-filter (#21488)
  • Give priority to pycapsule interface in from_dataframe (#21377)
  • Support writing Time type in json (#21454)
  • Activate all optimizations in sinks (#21462)
  • Add AssertionError variant to PolarsError in polars-error (#21460)
  • Pass filter to inner readers in multiscan new streaming (#21436)
🐞 Bug fixes
  • Categorical min/max panicking when string cache is enabled (#21552)
  • Don't encode IPC record batch twice (#21525)
  • Respect rewriting flag in Node rewriter (#21516)
  • Correct skip batch predicate for partial statistics (#21502)
  • Make the Parquet Sink properly phase aware (#21499)
  • Don't divide by zero in partitioned group-by (#21498)
  • Create new linearizer between rowwise new streaming sink phases (#21490)
  • Don't drop rows in sinks between new streaming phases (#21489)
  • Incorrect lazy schema for Expr.list.diff (#21484)
  • Give priority to pycapsule interface in from_dataframe (#21377)
  • Duration Series arithmetic operations (#21425)
  • Fix unwrap None panic when filtering delta with missing columns (#21453)
  • Use stable sort for rolling-groupby (#21444)
  • Throw exception if dataframe is too large to be compatible with Excel (#20900)
  • Address regression with read_excel not handling URL paths correctly (#21428)
📖 Documentation
  • Fix typo (#21554)
  • Correct typos and grammar in Python docstrings (#21524)
  • Move llm page under misc (#21550)
  • Polars Cloud docs (#21548)
  • Add LazyFrame.remote docs entry (#21529)
  • Specify that the key column must be sorted in ascending order in merge_sorted (#21501)
  • Add Polars & LLMs page to the user guide (#21218)
  • Mention that statistics=True doesn't enable all statistics in sink_parquet() (#21434)
🛠️ Other improvements
  • Don't take ownership of IRplan in new streaming engine (#21551)
  • Refactor code for re-use by streaming NDJSON source (#21520)
  • Simplify the phase handling of new streaming sinks (#21530)
  • Improve IPC sink node parallelism (#21505)
  • Use tikv-jemallocator (#21486)
  • Rename 'join_nulls' parameter to 'nulls_equal' in join functions (#21507)
  • Move rolling to polars-compute (#21503)
  • Remove Growable in favor of ArrayBuilder (#21500)
  • Introduce a Sink Node trait in the new streaming engine (#21458)
  • Add test for rolling stability sort (#21456)
  • Add test for empty .is_in predicate filter (#21455)
  • Test for unique length on multiple columns (#21418)

Thank you to all our contributors for making this release possible! @Kevin-Patyk, @MarcoGorelli, @Matt711, @alexander-beedie, @banflam, @braaannigan, @coastalwhite, @dependabot[bot], @etiennebacher, @ghuls, @kevinjqliu, @lukemanley, @mcrumiller, @nameexhaustion, @orlp, @ritchie46, @stijnherfst, @thomasjpfan and dependabot[bot]

View originalPermalink
How 1.24.0 went
1.23.0

Python Polars 1.23.0

Added 12
  • Implement i128 to str cast
  • Connect polars-cloud
  • Version DSL
  • Filter hive files using predicates in new streaming
  • Add negative slicing to new streaming multiscan
  • Implement sorted flags for struct series
Changed 6
  • Toggle projection pushdown for eager rolling
  • Fix pathologic rolling + group-by performance and memory explosion
  • Add sampling to new-streaming equi join to decide between build/probe side
  • Make user facing binary formats mostly self describing
  • Allow iterable of frames as input to align_frames
  • Rename credentials parameter to credential in CredentialProviderAzure
Fixed 5
  • Method dt.ordinal_day was returning UTC results as opposed to those on the local timestamp
  • Use Kahan summation for rolling sum kernels to fix numerical stability issues
  • Add scalar checks for n and fill_value parameters in shift
  • Upcast small integer dtypes for rolling sum operations
  • Don't silently produce null values from invalid input to pl.datetime and pl.date
🚀 Performance improvements
  • Toggle projection pushdown for eager rolling (#21405)
  • Fix pathologic rolling + group-by performance and memory explosion (#21403)
  • Add sampling to new-streaming equi join to decide between build/probe side (#21197)
✨ Enhancements
  • Implement i128 -> str cast (#21411)
  • Connect polars-cloud (#21387)
  • Version DSL (#21383)
  • Make user facing binary formats mostly self describing (#21380)
  • Filter hive files using predicates in new streaming (#21372)
  • Add negative slicing to new streaming multiscan (#21219)
  • Allow iterable of frames as input to align_frames (#21209)
  • Implement sorted flags for struct series (#21290)
  • Support reading arrow Map type from Delta (#21330)
  • Add a dedicated remove method for DataFrame and LazyFrame (#21259)
  • Rename credentials parameter to credential in CredentialProviderAzure (#21295)
  • Implement merge_sorted for struct (#21205)
  • Add positive slice for new streaming MultiScan (#21191)
  • Don't take in rewriting visitor (#21212)
  • Add SQL support for the DELETE statement (#21190)
  • Add row index to new streaming multiscan (#21169)
  • Improve DataFrame fmt in explain (#21158)
🐞 Bug fixes
  • Method dt.ordinal_day was returning UTC results as opposed to those on the local timestamp (#21410)
  • Use Kahan summation for rolling sum kernels. Fix numerical stability issues (#21413)
  • Add scalar checks for n and fill_value parameters in shift (#21292)
  • Upcast small integer dtypes for rolling sum operations (#21397)
  • Don't silently produce null values from invalid input to pl.datetime and pl.date (#21013)
  • Allow duration multiplied w/ primitive to propagate in IR schema (#21394)
  • Struct arithmetic broadcasting behavior (#21382)
  • Prefiltered optional plain primitive kernel (#21381)
  • Panic when projecting only row index from IPC file (#21361)
  • Properly update groups after gather in aggregation context (#21369)
  • Mark test as may_fail_auto_streaming (#21373)
  • Properly set fast_unique in EnumBuilder (#21366)
  • Rust test race condition (#21368)
  • Fix unequal DataFrame column heights from parquet hive scan with filter (#21340)
  • Fix ColumnNotFound error selecting len() after semi/anti join (#21355)
  • Merge Parquet nested and flat decoders (#21342)
  • Incorrect atomic ordering in Connector (#21341)
  • Method dt.offset_by was discarding month and year info if day was included in offset for timezone-aware columns (#21291)
  • Fix pickling polars.col on Python versions <3.11 (#21333)
  • Fix duplicate column names after join if suffix already present (#21315)
  • Skip Batches Expression for boolean literals (#21310)
  • Fix performance regression for eager join_where (#21308)
  • Fix incorrect predicate pushdown for predicates referring to right-join key columns (#21293)
  • Panic in to_physical for series of arrays and lists (#21289)
  • Resolve deadlock due to leaking in Connector recv drop (#21296)
  • Incorrect result for merge_sorted with lexical categorical (#21278)
  • Add Int128 path for join_asof (#21282)
  • Categorical min/max returning String dtype rather than Categorical (#21232)
  • Checking overflow in Sliced function (#21207)
  • Adding a struct field using a literal raises InvalidOperationError (#21254)
  • Return nulls for is_finite, is_infinite, and is_nan when dtype is pl.Null (#21253)
  • Account for minor change in new connectorx release (#21277)
  • Properly implement and test Skip Batch Predicate (#21269)
  • Infinite recursion when broadcasting into struct zip_outer_validity (#21268)
  • Deadlock due to bad logic in new-streaming join sampling (#21265)
  • Incorrect result for top_k/bottom_k when input is sorted (#21264)
  • UTF-8 validation of nested string slice in Parquet (#21262)
  • Raise instead of panicking when casting a Series to a Struct with the wrong number of fields (#21213)
  • Defer credential provider resolution to take place at query collection instead of construction (#21225)
  • Do not panic in strptime() if format ends with '%' (#21176)
  • Raise error instead of panicking for unsupported SQL operations (#20789)
  • Projection of only row index in new streaming IPC (#21167)
  • Fix projection count query optimization (#21162)
📖 Documentation
  • Fix doc for SQL Functions navigation (#21412)
  • Fix initial selector example (#21321)
  • Add pandas strictness API difference (#21312)
  • Improve Expr.name.map docstring example (#21309)
  • Add logo to Ask AI (#21261)
  • Fix docs for Catalog (#21252)
  • AI widget again (#21257)
  • Revert plugin (#21250)
  • Add kappa ask ai widget (#21243)
  • Update social icons in API reference docs (#21214)
  • Improve Arrow key feature description (#21171)
  • Improve example in IO plugins user guide (#21146)
🛠️ Other improvements
  • Move storage of hive partitions to DataFrame (#21364)
  • Feature gate merge sorted in new streaming engine (#21338)
  • Remove new streaming old multiscan (#21300)
  • Add tests for fixed open issues (#21185)
  • Try to mimic all steps (#21249)
  • Require version for POLARS_VERSION (#21248)
  • Fix docs (#21246)
  • Avoid unnecessary packaging dependency (#21223)
  • Remove unused file (#21240)
  • Add use_field_init_shorthand = true to rustfmt (#21237)
  • Don't mutate arena by default in Rewriting Visitor (#21234)
  • Disable the TraceMalloc allocator (#21231)
  • Add feature gate to old streaming deprecation warning (#21179)
  • Install seaborn when running remote benchmark (#21168)

Thank you to all our contributors for making this release possible! @GiovanniGiacometti, @JakubValtar, @MarcoGorelli, @Matt711, @Shoeboxam, @YichiZhang0613, @alexander-beedie, @bschoenmaeckers, @coastalwhite, @edwinvehmaanpera, @erikbrinkman, @etiennebacher, @hemanth94, @henryharbeck, @jqnatividad, @lukemanley, @mcrumiller, @nameexhaustion, @orlp, @r-brink, @ritchie46 and @ydagosto

View originalPermalink
How 1.23.0 went
1.22.0

Python Polars 1.22.0

Added 6
  • Add dedicated concatenate kernels
  • Add projection pushdown to new streaming multiscan
  • Implement join on struct dtype
  • Enable ingest of objects supporting the PyCapsule interface via from_arrow
  • Enable new streaming multiscan for CSV
  • Add environment POLARS_MAX_CONCURRENT_SCANS in multiscan for new streaming
Changed 14
  • Reduce sharing in stringview arrays in new-streaming equijoin
  • Implement native Expr.count() on new-streaming
  • Speed up list operations that use amortized_iter()
  • Use Cow as output for rechunk and add rechunk_mut
  • Reduce arrow slice mmap overhead
  • Reduce conversion cost in chunked string gather
Fixed 1
  • Fix Expr.over applying scale incorrectly for Decimal types
🚀 Performance improvements
  • Reduce sharing in stringview arrays in new-streaming equijoin (#21129)
  • Implement native Expr.count() on new-streaming (#21126)
  • Speed up list operations that use amortized_iter() (#20964)
  • Use Cow as output for rechunk and add rechunk_mut (#21116)
  • Reduce arrow slice mmap overhead (#21113)
  • Reduce conversion cost in chunked string gather (#21112)
  • Enable prefiltered by default for new streaming (#21109)
  • Enable parquet column expressions for streaming (#21101)
  • Deduplicate buffers again in stringview concat kernel (#21098)
  • Add dedicated concatenate kernels (#21080)
  • Rechunk only once during join probe gather (#21072)
  • Micro-optimise internal DataFrame height and width checks (#21071)
  • Speed up from_pandas when converting frame with multi-index columns (#21063)
  • Change default memory prefetch to MADV_WILLNEED (#21056)
  • Remove cast to boolean after comparison in optimizer (#21022)
  • Split last rowgroup among all threads in new-streaming parquet reader (#21027)
  • Recombine into larger morsels in new-streaming join (#21008)
  • Improve list.min and list.max performance for logical types (#20972)
  • Ensure count query select minimal columns (#20923)
✨ Enhancements
  • Add projection pushdown to new streaming multiscan (#21139)
  • Implement join on struct dtype (#21093)
  • Use unique temporary directory path per user and restrict permissions (#21125)
  • Enable ingest of objects supporting the PyCapsule interface via from_arrow (#21128)
  • Enable new streaming multiscan for CSV (#21124)
  • Environment POLARS_MAX_CONCURRENT_SCANS in multiscan for new streaming (#21127)
  • Ensure AWS credential provider sources AWS_PROFILE from environment after deserialization (#21121)
  • Multi/Hive scans in new streaming engine (#21011)
  • Add linear_spaces (#20941)
  • IO plugins suppport lazy schema (#21079)
  • Add write_table() function to Unity catalog client (#21089)
  • Add is_object method to Polars DataType class (#21074)
  • Implement merge_sorted for binary (#21045)
  • Hold string cache in new streaming engine and fix row-encoding (#21039)
  • Add CredentialProviderAzure parameter to accept user-instantiated azure credential classes (#21047)
  • Expose unity catalog dataclasses and type aliases (#21046)
  • Support max/min method for Time dtype (#19815)
  • Implement a streaming merge sorted node (#20960)
  • Automatically use temporary credentials API for scanning Unity catalog tables (#21020)
  • Add negative slice support to new-streaming engine (#21001)
  • Allow for more RG skipping by rewriting expr in planner (#20828)
  • Rename catalog schema to namespace (#20993)
  • Add functionality to create and delete catalogs, tables and schemas to Unity catalog client (#20956)
  • Allow custom JSONEncoder for the json_normalize function, minor speedup (#20966)
  • Support passing aws_profile in storage_options (#20965)
  • Improved support for KeyboardInterrupts (#20961)
  • Make the available concat alignment strategies more generic (#20644)
  • Extract timezone info from python datetimes (#20822)
  • Add hint for POLARS_AUTO_USE_AZURE_STORAGE_ACCOUNT_KEY to error message (#20942)
  • Filter Parquet pages with ParquetColumnExpr (#20714)
  • Expose descending and nulls last in window order-by (#20919)
🐞 Bug fixes
  • Fix Expr.over applying scale incorrectly for Decimal types (#21140)
  • Fix IO plugin predicate with failed serialization (#21136)
  • Ensure lit handles datetimes with tzinfo that represents a fixed offset from UTC (#21003)
  • Correctly implement take_(opt_)chunked_unchecked for structs (#21134)
  • Restore printing backtraces on panics (#21131)
  • Use microseconds for Unity catalog datetime unit (#21122)
  • Fix incorrect output height for SQL SELECT COUNT(*) FROM (#21108)
  • Validate/coerce types for comparisons within join_where predicates (#21049)
  • Do not auto-init credential providers if credential fetch returns error (#21090)
  • Fix join_where incorrectly dropping transformations on RHS of equality expressions (#21067)
  • Quadratic allocations when loading nested Parquet column metadata (#21050)
  • Invalidate sortedness flag when sorting from pl.Categorical to pl.Categorical("lexical") (#21044)
  • Calling top_k on list type panics (#21043)
  • Fix rolling on empty DataFrame panicking (#21042)
  • Fix set_tbl_width_chars panicking with negative width (#20906)
  • Ensure write_excel recognises the Array dtype and writes it out as a string (#20994)
  • Fix merge_sorted producing incorrect results or panicking for some logical types (#21018)
  • Fix all-null list aggregations returning Null dtype (#20992)
  • Ensure scalar-only with_columns are broadcasted on new-streaming (#20983)
  • Improve SQL interface behaviour when INTERVAL is not a fixed duration (#20958)
  • Address minor regression for one-column DataFrame passed to is_in expressions (#20948)
  • Add Arrow Float16 conversion DataType (#20970)
  • Revert length check of patterns in str.extract_many() (#20953)
  • Add maintain order for flaky new-streaming test (#20954)
  • Allow for respawning of new streaming sinks (#20934)
  • Ensure Function name correctness in cse (#20929)
  • Don't consume c_stream as iterable (#20899)
  • Validate pl.Array shape argument types (#20915)
  • Fix from_numpy returning Null dtype for empty 1D numpy array (#20907)
  • Consider the original dtypes when selecting columns in write_excel function (#20909)
  • Handle boolean comparisons in Iceberg predicate pushdown (#18199)
  • Fix map_elements panicking with Decimal type (#20905)
📖 Documentation
  • Replace pandas where with mask in Migrating -> Coming from Pandas (#21085)
  • Correct Arrow misconception (#21053)
  • Add example showing use of write_delta with delta_lake.WriterProperties (#20746)
  • Add missing shape param to Array docstring (#20747)
  • Add IO plugins to Python API reference (#21028)
  • Document IO plugins (#20982)
  • Ensure set_sorted description references single-column behavior (#20709)
📦 Build system
  • Speed up CI by running a few more tests in parallel (#21057)
🛠️ Other improvements
  • Add test for equality filters in Parquet (#21114)
  • Add various tests for open issues (#21075)
  • Upgrade packages and apply latest formatting (#21086)
  • Move python dsl and builder_dsl code to dsl folder (#21077)
  • Organize python related logics in polars-plan (#21070)
  • Improve binary dispatch (#21061)
  • Skip physical order test (#21060)
  • Fix new ruff lints (#21040)
  • Added test to check for the computation of list.len for null (#20938)
  • Add make fix for running cargo clippy --fix (#21024)
  • Add tests for resolved issues (#20999)
  • Update code coverage workflow to use macos-latest runners (#20995)
  • Remove unused arrow file (#20974)
  • Deprecate the old streaming engine (#20949)
  • Move dt.replace tests to dedicated file, add "typing :: typed" classifier, remove unused testing function (#20945)
  • Extract merge sorted IR node (#20939)
  • Update copyright year (#20764)
  • Move Parquet deserialization to BitmapBuilder (#20896)
  • Also publish polars-python (#20933)
  • Remove verify_dict_indices_slice from main (#20928)
  • Add tests for already resolved issues (#20921)
  • Fix the verify_dict_indices codegen (#20920)
  • Add ProjectionContext in projection pushdown opt (#20918)

Thank you to all our contributors for making this release possible! @FBruzzesi, @MarcoGorelli, @aberres, @alexander-beedie, @arnabanimesh, @bschoenmaeckers, @coastalwhite, @deanm0000, @dependabot[bot], @dimfeld, @eitsupi, @etiennebacher, @henryharbeck, @itamarst, @lmmx, @lukemanley, @mcrumiller, @mullimanko, @nameexhaustion, @orlp, @petrosbar, @ritchie46, @siddharth-vi, @skritsotalakis, @taureandyernv and dependabot[bot]

View originalPermalink
How 1.22.0 went
1.21.0

Python Polars 1.21.0

Added 6
  • Add `linear_space` function
  • Add unique operations for Decimal dtype
  • Add NDJson sink for the new streaming engine
  • Add CSV sink for the new streaming engine
  • Add experimental credential provider support for Delta read/scan/write
  • Add experimental unity catalog client
Changed 13
  • Stabilize methods and functions
  • Allow column expressions in DataFrame `unnest`
  • Improve string to temporal parsing in `read_excel` and `read_ods`
  • Implement df.unique() on new-streaming engine
  • Support nested keys in window functions
  • Support cumulative aggregations for Decimal dtype
Fixed 1
  • Incorrect scale used in `log` and `exp` for Decimal type
🚀 Performance improvements
  • Use BitmapBuilder in yet more places (#20868)
  • Make an owned version of append (#20800)
  • Use BitmapBuilder in a lot more places (#20776)
✨ Enhancements
  • Stabilize methods/functions (#20850)
  • Add linear_space (#20678)
  • Improve string → temporal parsing in read_excel and read_ods (#20845)
  • Implement df.unique() on new-streaming engine (#20875)
  • Experimental credential provider support for Delta read/scan/write (#20842)
  • Allow column expressions in DataFrame unnest (#20846)
  • Auto-initialize Python credential providers in more cases (#20843)
  • Add unique operations for Decimal dtype (#20855)
  • Add NDJson sink for the new streaming engine (#20805)
  • Support nested keys in window functions (#20837)
  • Add CSV sink for the new streaming engine (#20804)
  • Periodically check python signals ('CTRL-C' handling) (#20826)
  • Experimental unity catalog client (#20798)
  • Support cumulative aggregations for Decimal dtype (#20802)
  • Account for SurrealDB Python API updates (handle both SurrealDB and AsyncSurrealDB classes) in read_database (#20799)
  • Drop nest-asyncio in favor of custom logic (#20793)
  • Improve window function caching strategy (#20791)
  • Support lakefs:// URI for delta scanner (#20757)
  • Additional support for loading numpy.float16 values (as Float32) (#20769)
🐞 Bug fixes
  • Warn if asof keys not sorted (#20887)
  • Ensure explicit values given to column_widths override autofit in write_excel (#20893)
  • Avoid name collisions and panicking in object conversion (#20890)
  • Incorrect scale used in log and exp for Decimal type (#20888)
  • Don't deep clone manuallydrop in GroupsPosition (#20886)
  • Fix DuplicateError when selecting columns after join_where or cross join + filter (#20865)
  • Incorrect Decimal value for fill_null(strategy="one") (#20844)
  • Fix one edge case (out of many) of int128 literals not working (#20830)
  • Add height check to frame-level row indexing when key is int (#20778)
  • Remove assert that panics on group_by followed by head(n), where n is larger then the frame height (#20819)
  • Selectors should raise on + between themselves (#20825)
  • Fix panic InvalidHeaderValue scanning from S3 on Windows (#20820)
  • Fix clip for Decimal returning wrong values (#20814)
  • Incorrect height from slicing after projecting only the file path column (#20817)
  • Shift mask when skipping Bitpacked values in Parquet (#20810)
  • Error instead of truncate if length mismatch for several str functions (#20781)
  • Support cumulative aggregations for Decimal dtype (#20802)
  • Allow is_in values to be given as custom Collection (#20801)
  • Propagate null instead of panicking in pl.repeat_by() (#20787)
  • Do not print sensitive information to output on POLARS_VERBOSE (#20797)
  • Ignore file cache allocation error if fallocate() is not permitted (#20796)
  • Incorrect logic in assert_series_equal for infinities (#20763)
📖 Documentation
  • Update source URL for legislators-historical.csv (#20858)
  • Update ML part of ecosystem user guide page (#20596)
🛠️ Other improvements
  • Disable 'catalog' in build (#20897)
  • Implement negative slice for new streaming IPC (#20866)
  • Debloat Series bitops (#20873)
  • Reduce python map bloat (#20871)
  • Remove todo and test restriction for new-streaming (#20861)
  • Dispatch to the in-mem engine for AExpr::Gather (#20862)
  • Dispatch to the in-memory engine for multifile sources (#20860)
  • Add tests for open issues (#20857)
  • Mark 'register_startup' as unsafe (#20841)
  • Reduce mode bloat (#20839)
  • Rename ContainsMany to ContainsAny (#20785)
  • Unpin NumPy in type checking workflow (#20792)
  • Add various tests (#20768)
  • Small drive-by's (#20772)
  • Touch the upload probe for the remote benchmark (#20767)

Thank you to all our contributors for making this release possible! @alexander-beedie, @arnabanimesh, @braaannigan, @burakemir, @coastalwhite, @etiennebacher, @ion-elgreco, @itamarst, @lukemanley, @mcrumiller, @nameexhaustion, @orlp, @ritchie46 and @stinodego

View originalPermalink
How 1.21.0 went
1.20.0

Python Polars 1.20.0

Added 10
  • Add SQL support for the NORMALIZE string function
  • Add 'allow_exact_matches' parameter to join_asof
  • Add new-streaming first/last aggregations
  • Add Parquet Sink to new streaming engine
  • Add str.normalize() function
  • Support loading Excel Table objects by name
Changed 6
  • Allow different python versions for pickle
  • Make automatic use of Azure storage account keys opt-in
  • Reduce scan_csv() memory usage when using BytesIO
  • Allow more group_by agg expressions in the new streaming engine
  • Update sqlparser-rs, enabling LEFT keyword to be optional for anti/semi joins in SQL queries
  • Officially support Python 3.13
Fixed 5
  • Fix unique(maintain_order=True) raising InvalidOperationError for null array
  • Fix incorrect top-k by sorted column and head() returning extra rows
  • Fix join_asof panicking for invalid tolerance input
  • Fix Int128 dtype serialization
  • Ensure SQL LIKE and ILIKE operators support multi-line matches
Deprecated 1
  • Make parameter of str.to_decimal keyword-only
⚠️ Deprecations
  • Make parameter of str.to_decimal keyword-only (#20570)
🚀 Performance improvements
  • Extend functionality on BitmapBuilder and use in Growables (#20754)
  • Specialize first/last agg for simple types in new-streaming engine (#20728)
  • Use PyO3 to convert between Python and Rust datetimes (#20660)
  • Improve state caching and parallelism of window functions (#20689)
  • Broadcast without materialization in concat_arr (#20681)
  • Cache rolling groups (#20675)
  • Use downcast_ref instead of dtype equality in <dyn SeriesTrait as AsRef<ChunkedArray<T>> (#20664)
  • Fix performance regression for DataFrame serialization/pickling (#20641)
  • Make Parquet verify_dict_indices SIMD (#20623)
  • Move to zlib-rs by default and use zstd::with_buffer (#20614)
  • Skip filter expansion in eager (#20586)
  • Improve unique pred-pd (#20569)
✨ Enhancements
  • Allow different python versions for pickle (#20740)
  • Add SQL support for the NORMALIZE string function (#20705)
  • Add 'allow_exact_matches' join_asof' (#20723)
  • Add new-streaming first/last aggregations (#20716)
  • Add Parquet Sink to new streaming engine (#20690)
  • Make automatic use of Azure storage account keys opt-in (#20652)
  • Reduce scan_csv() (and friends') memory usage when using BytesIO (#20649)
  • Improve GroupsProxy/GroupsPosition to be sliceable and cheaply cloneable (#20673)
  • Add str.normalize() (#20483)
  • Allow more group_by agg expressions in the new streaming engine (#20663)
  • Support loading Excel Table objects by name (#20654)
  • Support writing to file objects from write_excel (#20638)
  • Raise DuplicateError if given a pyarrow Table object with duplicate column names (#20624)
  • Support writing partitioned parquet to cloud (#20590)
  • Add hint to error message for extra struct field in JSON (#20612)
  • Add index_of() function to Series and Expr (#19894)
  • Update sqlparser-rs, enabling "LEFT" keyword to be optional for anti/semi joins in SQL queries (#20576)
  • Add cat.starts_with/cat.ends_with (#20257)
🐞 Bug fixes
  • Avoid blocking on async runtime when resolving cloud scans (#20750)
  • Fix allow_invalid_certificates being ignored in storage_options (#20744)
  • Incorrect output type for map_groups returning all-NULL column (#20743)
  • Fix unique(maintain_order=True) raising InvalidOperationError for null array (#20737)
  • Don't collapse into a Nested Loop Join if the cross join maintains order (#20729)
  • Don't serialize credentials provider (#20741)
  • Fix Series.n_unique raising for list of struct (#20724)
  • Fix incorrect top-k by sorted column, fix head() returning extra rows (#20722)
  • Add outer validity to AnyValueBufferTrusted for structs (#20713)
  • Don't partition group-by with non-scalar literals in agg (#20704)
  • Fix xor operation of selector with Expr (#20702)
  • Incorrect view buffer dedup (#20691)
  • Only verify Parquet ConvertedType if no LogicalType is given (#20682)
  • Validate length of schema_overrides in read_csv (#20672)
  • Fix map_elements ignoring skip_nulls=True for struct dtype (#20668)
  • Check for MAP-GROUPS in cloud-eligible (#20662)
  • Fix empty output of to_arrow() on filtered unit height DataFrame (#20656)
  • Add .default to azure credential provider scope URL (#20651)
  • Fix join_asof panicking for invalid tolerance input (#20643)
  • Incorrect flag check on is_elementwise (#20646)
  • Don't panic but set null type if type is unknown (#20647)
  • Fix performance regression for DataFrame serialization/pickling (#20641)
  • Fix Int128 dtype serialization (#20629)
  • Ensure read_excel and read_ods support reading from raw bytes for all engines (#20636)
  • Ensure that SQL LIKE and ILIKE operators support multi-line matches (#20613)
  • Properly broadcast in sort_by (#20434)
  • Properly load nested Parquet Statistics (#20610)
  • AWS environment config was not loaded when credential provider was used (#20611)
  • Fix order observability of group-by-dyn (#20615)
  • Soundness when loading Parquet string statistics (#20585)
  • Fix error filtering after with_columns() on unit height LazyFrame (#20584)
  • Propagate tenant_id to CredentialProviderAzure if given (#20583)
  • Restore symbols on Apple by bumping nightly version (#20563)
  • Fix type annotation of str.strip_chars_* methods (#20565)
  • Fix variable name in error message for "unsupported data type" in rolling and upsampling operations (#20553)
📖 Documentation
  • Add more information for cross joins (#20753)
  • Fix typo in sql functions (cosinus -> cosine) (#20676)
  • Add links to read_excel "engine_options" and "read_options" docstring (#20661)
  • Fix small typo in plugins (polars-dt -> polars-st) (#20657)
  • Add polars-h3 and polars-st to plugin list (#20653)
  • Add docs reference for Field (#20625)
  • Update DataFrame join examples (#20587)
  • Miscellaneous minor updates/fixes (#20573)
  • Update "group_by_rolling" (deprecated) to "rolling" in user guide (#20548)
📦 Build system
  • Update to official release of PyO3 0.23.4 (#20683)
  • Officially support Python 3.13 (#20549)
🛠️ Other improvements
  • Fix remote benchmark script (#20755)
  • Fix tests (#20745)
  • Simplify hive predicate handling in NEW_MULTIFILE (#20730)
  • Add tests for various open issues (#20720)
  • Fixes an Excel test following new fastexcel release (#20703)
  • Add tests for various open issues that have been fixed (#20680)
  • Don't include debug symbols in benchmark run (#20571)
  • Implement CSV, IPC and NDJson in the MultiScanExec node (#20648)
  • Don't rely on argument order of optimization_toggle (#20622)
  • Fix Python deps installation in remote-benchmark workflow (#20619)
  • Fix flaky categorical test (#20591)
  • Bump multiversion from 0.7 to 0.8 (#20543)
  • Remove unused nested function in LazyFrame.fill_null (#20558)
  • Improve bin size info (#20551)

Thank you to all our contributors for making this release possible! @Jesse-Bakker, @MarcoGorelli, @MoizesCBF, @SamuelAllain, @alexander-beedie, @bschoenmaeckers, @coastalwhite, @eitsupi, @etiennebacher, @itamarst, @jqnatividad, @lukemanley, @mcrumiller, @nameexhaustion, @orlp, @ritchie46 and @stinodego

View originalPermalink
How 1.20.0 went
1.19.0

Python Polars 1.19.0

Added 5
  • Add Int128 IO support for csv and ipc
  • Support arbitrary expressions in join_where
  • Add an include_file_paths parameter to read_excel and read_ods
  • Allow loading data from multiple Excel/ODS workbooks and worksheets
  • Implement list.min and list.max for list[i128]
Changed 6
  • Allow use of Python types in cs.by_dtype and col
  • Accept more generic Iterable[bool] in Series.filter
  • Allow more join lossless casting
  • Collapse expanded filters in eager
  • Use different binview dedup strategy depending on chunks ratio
  • Re-enable common subplan elim for new-streaming engine
Fixed 9
  • Output index type instead of u32 for sum_horizontal with boolean inputs
  • Fix more global categorical issues
  • Revert categorical unique code
  • Add unique fast path for empty categoricals
  • Fix various Int128 operations
  • Fix global cat unique
🚀 Performance improvements
  • Collapse expanded filters in eager (#20493)
  • Remove predicate from IR::DataFrame (#20492)
  • Use different binview dedup strategy depending on chunks ratio (#20451)
  • Generalize the arg_sort fast path onto Column (#20437)
  • Dedup binviews up front (#20449)
  • Re-enable common subplan elim for new-streaming engine (#20443)
  • Don't collect all LHS arrays in gather (#20441)
  • Remove prepare_series for gather kernels (#20439)
  • Don't always take all data buffers when gathering views (#20435)
✨ Enhancements
  • Add Int128 IO support for csv & ipc (#20535)
  • Support arbitrary expressions in 'join_where' (#20525)
  • Allow use of Python types in cs.by_dtype and col (#20491)
  • Add an "include_file_paths" parameter to read_excel and read_ods (#20476)
  • Allow more join lossless casting (#20474)
  • Accept more generic Iterable[bool] in Series.filter (#20431)
  • Allow loading data from multiple Excel/ODS workbooks and worksheets (#20465)
🐞 Bug fixes
  • Output index type instead of u32 for sum_horizontal with boolean inputs (#20531)
  • Fix more global categorical issues (#20547)
  • Update eager join doctest on multiple columns (#20542)
  • Revert categorical unique code (#20540)
  • Add unique fast path for empty categoricals (#20536)
  • Fix various Int128 operations (#20515)
  • Fix global cat unique (#20524)
  • Fix union (#20523)
  • Fix rolling aggregations for various integer types (#20512)
  • Ensure ignore_nulls is respected in horizontal sum/mean (#20469)
  • Fix incorrectly added sorted flag after append for lexically ordered categorical series (#20414)
  • More Int128 testing and related fixes (#20494)
  • Validate column names in unique() for empty DataFrames (#20411)
  • Implement list.min and list.max for list[i128] (#20488)
  • Decimal from physical in horizontal min/max and shift (#20487)
  • Don't remove sort if first/last strategy is set in unique (#20481)
  • Fix join literal behavior (#20477)
  • Validate asof join by args in IR resolving phase (#20473)
  • Fix align_frames with single row panicking (#20466)
  • Allow multiple column sort for Decimal (#20452)
  • Fix mode panicking for String dtype (#20458)
  • Return correct schema for sum_horizontal with boolean dtype (#20459)
  • Fix return type for add_business_days, millennium, century and combine methods in Series.dt namespace (#20436)
📖 Documentation
  • Fix typo in DataFrame.cast (#20532)
  • Fix flaky doctests (#20516)
  • Add examples for bitwise expressions (#20503)
  • Clarify the join pre-condition of join_asof (#20509)
  • Fix Expr.all description of Kleene logic (#20409)
🛠️ Other improvements
  • Increase categorical test coverage (#20514)
  • Report wheel sizes (#20541)
  • Add tests for floor/ceil on integers (#20479)
  • Expose and rewrite 'can_pre_agg' (#20450)
  • Skip test on windows; kuzu import segfaults (#20463)
  • Add a TypeCheckRule to the optimizer (#20425)

Thank you to all our contributors for making this release possible! @Biswas-N, @IndexSeek, @Prathamesh-Ghatole, @Terrigible, @alexander-beedie, @brifitz, @coastalwhite, @dependabot, @dependabot[bot], @jqnatividad, @lukemanley, @mcrumiller, @orlp, @ritchie46 and @siddharth-vi

View originalPermalink
How 1.19.0 went
1.18.0

Python Polars 1.18.0

Added 11
  • Add new Int128Type
  • Support loading data from multiple Excel/ODS workbooks
  • Add drop_empty_cols parameter for read_excel and read_ods
  • Add FirstArgLossless supertype
  • Add dt.replace
  • Polars build for Pyodide
Changed 8
  • Always resolve dynamic types in schema
  • Enable joins between compatible differing numeric key columns
  • Cache dtype on ExprIR
  • Serialize DataFrame/Series using IPC in serde
  • Allow subtraction of time dtype columns
  • Allow decoding of non-Polars arrow dictionaries in Arrow and Parquet
  • Expose AexprArena
  • Update pyo3 and numpy crates to version 0.23
Fixed 2
  • Fix nullable object in map_elements
  • Properly handle to_physical_repr of nested types
🏆 Highlights
  • Add new Int128Type (#20232)
🚀 Performance improvements
  • Order observability optimizations (#20396)
  • Purge ChunkedArray Metadata (#20371)
  • Explicit transpose in new-streaming equi-join finalize (#20363)
  • Cache dtype on ExprIR (#20331)
  • Lower overhead for BytecodeParser on introspection of incompatible UDFs (#20280)
✨ Enhancements
  • Always resolve dynamic types in schema (#20406)
  • Support loading data from multiple Excel/ODS workbooks (#20404)
  • Add "drop_empty_cols" parameter for read_excel and read_ods (#20430)
  • Order observability optimizations (#20396)
  • Add FirstArgLossless supertype (#20394)
  • Add dt.replace (#19708)
  • Polars build for Pyodide (#20383)
  • Add Azure credential provider using DefaultAzureCredential() (#20384)
  • Add env var to ignore file cache allocate error (#20356)
  • Enable joins between compatible differing numeric key columns (#20332)
  • Cache dtype on ExprIR (#20331)
  • Serialize DataFrame/Series using IPC in serde (#20266)
  • Improve error message on SchemaError (#20326)
  • Use better error messages when opening files (#20307)
  • Add 'skip_lines' for CSV (#20301)
  • Allow subtraction of time dtype columns (#20300)
  • Add bin.reinterpret (#20263)
  • Allow decoding of non-Polars arrow dictionaries in Arrow and Parquet (#20248)
  • Streamline creation of empty frame from Schema (#20267)
  • Add cat.len_chars and cat.len_bytes (#20211)
  • Expose AexprArena (#20230)
🐞 Bug fixes
  • Fix nullable object in map_elements (#20422)
  • Properly handle to_physical_repr of nested types (#20413)
  • Properly raise UDF errors (#20417)
  • Workaround for mmap crash under Emscripten (#20418)
  • Fix using new_columns in scan_csv with compressed file (#20412)
  • Fix return type of Series.dt.add_business_days (#20402)
  • Fix decimal series dispatch (#20400)
  • Fix decimal arithmetic schema (#20398)
  • Raise on categorical search_sorted (#20395)
  • Fix plotting f-strings and docstrings (#20399)
  • Don't try to load non-existend List/FSL statistics (#20388)
  • Propagate nulls for float methods on all numeric types (#20386)
  • Add env var to ignore file cache allocate error (#20356)
  • Flip order on right join (#20358)
  • Correctly parse special float values in from_repr (#20351)
  • Fix incorrect object store caching for ADLS URI (#20357)
  • Use the same encoding for nullable as non-nullable arrays (#20323)
  • Improve error message on SchemaError (#20326)
  • Boolean optional slice pushdown (#20315)
  • Properly handle from_physical for List/Array (#20311)
  • Ignore quotes in csv comments (#20306)
  • Ensure pl.datetime returns empty column when input columns are empty (#20278)
  • Ensure output height does not change on lazy projection pushdown with aggregations (#20223)
  • Fix error writing on Windows to locations outside of C drive (#20245)
  • Incorrect comparison in some cases with filtered list/array columns (#20243)
  • Ensure height is maintained in SQL SELECT 1 FROM (#20241)
  • Properly account for updated Categorical in .unique() kernel (#20235)
📖 Documentation
  • Improve docstring clarity (#20416)
  • Update GPU engine installation instructions to remove --extra-index-url from CUDA 12 packages (#20381)
  • Remove Plugins overview page without information (#20348)
  • Small fixes/clarifications in user guide (#20335)
  • Improve docs about NaN (#20310)
  • Fix substr function param definition (#19054)
  • Include parquet options in BigQuery I/O write sample (#20292)
  • Fix typo in fork warning (#20258)
📦 Build system
  • Add project.dynamic = ["version"] to pyproject.toml (#20345)
  • Update pyo3 and numpy crates to version 0.23 (#20111)
  • Build wheels for ARM Windows in Python release workflow (#20247)
🛠️ Other improvements
  • Enable masked out list, struct and array elements in parametric tests (#20365)
  • Move hive partitioning/multi-file handling outside of readers (#20203)
  • Purge ChunkedArray Metadata (#20371)
  • Correcting misspelled return value and unifying regional spelling (#20375)
  • Add test for select(len()) (#20343)
  • Make parametric tests include pl.List and pl.Array by default (#20319)
  • Use Column in Row Encoding (#20312)
  • Don't warn on fork hook (#20309)
  • Don't deconstruct CsvParseOptions (#20302)
  • Allow decoding of non-Polars arrow dictionaries in Arrow and Parquet (#20248)
  • Prepare test suite for Python 3.13 support (#20297)
  • Add FunctionCastOptions and conservative IR-level cast type-checking (#20286)
  • Add more descriptive error message for failure of vstack/extend (#20299)
  • Clean up some remnants of Python 3.8 support (#20293)
  • Add new Int128Type (#20232)
  • Add test for BytesIO overwritten after scan (#20240)
  • Expose AexprArena (#20230)

Thank you to all our contributors for making this release possible! @Jesse-Bakker, @Terrigible, @ZemanOndrej, @alexander-beedie, @balbok0, @beckernick, @bschoenmaeckers, @coastalwhite, @georgestagg, @hamdanal, @haocheng6, @kszlim, @lukemanley, @mcrumiller, @nameexhaustion, @noexecstack, @orlp, @ptiza, @r-brink, @ritchie46, @rodrigogiraoserrao, @stijnherfst, @stinodego, @tswast and @zero-stroke

View originalPermalink
How 1.18.0 went
1.17.1

Python Polars 1.17.1

Fixed 2
  • Fix incorrect lazy select(len()) with some select orderings
  • Fix assertion panic on LazyFrame scratch.is_empty()
🐞 Bug fixes
  • Fix incorrect lazy select(len()) with some select orderings (#20222)
  • Fix assertion panic on LazyFrame scratch.is_empty() (#20219)

Thank you to all our contributors for making this release possible! @nameexhaustion and @ritchie46

View originalPermalink
How 1.17.1 went
1.17.0

Python Polars 1.17.0

Added 5
  • Add fast paths for series.arg_sort and dataframe.sort
  • Allow sorting of lists and arrays
  • Add maintain_order parameter to joins
  • Add lazy support for pl.select
  • Experimental cloud write support
Changed 10
  • Much faster Series construction from subclasses of standard Python types
  • Construct Series for bytes/binary data 10x faster when dtype not explicitly set
  • Reduce memory copy when scanning from Python objects
  • Utilize the RangedUniqueKernel for Enum/Categorical
  • Don't instantiate validity mask when unneeded in Parquet
  • Retry with reloaded credentials on cloud error
Fixed 4
  • Don't trigger length check in array construction
  • Allow row encoding for 32-bit architectures (e.g. WASM)
  • Properly project unordered column in parquet prefiltered
  • Csv stop simd cache if eol char is hit
Deprecated 1
  • Deprecate ddof parameter for correlation coefficient
🚀 Performance improvements
  • Add fast paths for series.arg_sort and dataframe.sort (#19872)
  • Much faster Series construction from subclasses of standard Python types (#20166)
  • Utilize the RangedUniqueKernel for Enum/Categorical (#20150)
  • Reduce memory copy when scanning from Python objects (#20142)
  • Construct Series for bytes/binary data 10x faster when dtype not explicitly set (#20157)
  • Don't instantiate validity mask when unneeded in Parquet (#20149)
✨ Enhancements
  • Retry with reloaded credentials on cloud error (#20185)
  • Support reading Enum dtype from csv (#20188)
  • Improve dtype inference and load for DataFrame cols constructed from Python Enum values (#20180)
  • Allow sorting of lists and arrays (#20169)
  • Add maintain_order parameter to joins (#20026)
  • Allow for to_datetime / strftime to automatically parse dates with single-digit hour/minute/second (#20144)
  • Issue warning when using to_struct() without a list of field names (#20158)
  • Experimental cloud write support (#20129)
  • Add lazy support for pl.select (#20091)
  • Enable view arrow export in write_delta (#20092)
🐞 Bug fixes
  • Don't trigger length check in array construction (#20205)
  • Allow row encoding for 32-bit architectures (e.g. WASM) (#20186)
  • Properly project unordered column in parquet prefiltered (#20189)
  • Csv stop simd cache if eol char is hit (#20199)
  • Estimated size for object (#20191)
  • Respect parallel argument in parquet (#20187)
  • Only validate UTF-8 for selected items when all below len 128 (#20183)
  • Serialize categories of Enum in arrow metadata (#20181)
  • Don't use RLE encoding for Parquet Boolean (#20172)
  • Invalid bitwise_xor for ScalarColumn (#20140)
  • Series construct with large nested u64 (#20167)
  • Add temporal feature gate in is_elementwise_top_level (#20177)
  • Column name mismatch or not found in Parquet scan with filter (#20178)
  • Raise if apply returns different types (#20168)
  • Deal with masked out list elements (#20161)
  • Fix index out of bounds in uniform_hist_count (#20133)
  • Implement arg_sort for Null series (#20135)
  • Handle slice pushdown in PythonUDF GroupBy (#20132)
  • Check shape for *_horizontal functions (#20130)
  • Properly coerce types in lists (#20126)
  • Incorrect aggregation of empty groups after slice (#20127)
  • DataFrame .get_column after drop_in_place (#20120)
  • Subtraction with underflow on empty FixedSizeBinaryArray (#20109)
  • Materialize smallest dyn ints to use feature gate for i8/i16 (#20108)
  • Return null instead of 0. for rolling_std when window contains a single element and ddof=1 and there are nulls elsewhere in the Series (#20077)
  • Only slice after sort when slice is smaller than frame length (#20084)
  • Preserve Series name in __rpow__ operation (#20072)
  • Allow nested is_in() in when()/then() for full-streaming (#20052)
📖 Documentation
  • Add more Rust examples to User Guide (#20194)
  • Expand plotting docs (#19719)
  • Fix Rust examples in user guide (#20075)
  • Update by param description for rolling_*_by functions (#19715)
  • Correct supported compression formats (#20085)
  • Specify strictness in cast (#20067)
📦 Build system
  • Upgrade sqlparser-rs from version 0.49 to 0.52 (#20110)
  • Bump memmap2 to version 0.9 (#20105)
  • Bump object_store to version 0.11 (#20102)
  • Bump fs4 to version 0.12 (#20101)
  • Bump thiserror to version 2 (#20097)
  • Bump atoi_simd to version 0.16 (#20098)
  • Bump chrono-tz to 0.10 (#20094)
  • Update Rust dependency ndarray to 0.16 (#20093)
  • Bump Rust toolchain to nightly-2024-11-28 (#20064)
🛠️ Other improvements
  • Deprecate ddof parameter for correlation coefficient (#20197)
  • Move Bitwise aggregations to FunctionExpr (#20193)
  • Add ragged lines test (#20182)
  • Set delta version check higher (#20153)
  • Fix typo in assertion in datatype copy test (#20121)
  • Move horizontal methods to polars-ops (#20134)
  • Remove useless SeriesTrait::get implementations (#20136)
  • Add a bunch more automated row encoding sortedness tests (#20056)

Thank you to all our contributors for making this release possible! @DzenanJupic, @MarcoGorelli, @YichiZhang0613, @alexander-beedie, @coastalwhite, @dependabot, @dependabot[bot], @flowlight0, @henryharbeck, @iharthi, @ion-elgreco, @jqnatividad, @lukapeschke, @lukemanley, @mcrumiller, @nameexhaustion, @ptiza, @ritchie46, @siddharth-vi, @stijnherfst, @stinodego and @wsyxbcl

View originalPermalink
How 1.17.0 went
1.16.0

Python Polars 1.16.0

Added 3
  • Enable creation of independently reusable Config instances
  • Add optimized row encoding for Decimals
  • Add drop_nans method to DataFrame and LazyFrame
Changed 4
  • Expand more filters
  • Cache the DataFrame schema in get_column_index
  • Improved error message on invalid Python Enum init
  • Improve Polars Enum dtype init from standard Python enums
Fixed 12
  • Improve hist binning around breakpoints
  • Fix invalid len due to projection pushdown selection of scalar
  • Fix empty scalar agg type
  • Improve binning in Series.hist with bin_count when all values are the same
  • Less intrusive forking warnings
  • Reading nullable sliced / masked Categoricals from Parquet
Removed 1
  • Remove note about guaranteed left join order
💥 Breaking changes
  • Remove note about guaranteed left join order (#20048)
🚀 Performance improvements
  • Expand more filters (#20022)
  • Cache the DataFrame schema in get_column_index (#20021)
✨ Enhancements
  • Enable creation of independently reusable Config instances (#20053)
  • Improved error message on invalid Python Enum init (#20060)
  • Improve Polars Enum dtype init from standard Python enums (#19997)
  • Add optimized row encoding for Decimals (#20050)
  • Add drop_nans method to DataFrame and LazyFrame (#20029)
🐞 Bug fixes
  • Improve hist binning around breakpoints (#20054)
  • Fix invalid len due to projection pushdown selection of scalar (#20049)
  • Fix empty scalar agg type (#20051)
  • Improve binning in Series.hist with bin_count when all values are the same (#20034)
  • Less intrusive forking warnings (#20032)
  • Reading nullable sliced / masked Categoricals from Parquet (#20024)
  • Regression in hist panicking on out of bounds index (#20016)
  • Fix starts_with out of bounds (#20006)
  • Fix incorrect column order for parquet scan with hive columns in file (#19996)
  • Incorrectly gave list.len() for masked-out rows (#19999)
  • Bug fix in existing fast path for sorted series (#20004)
  • Incorrect collect_schema() for fill_null() after an aggregation expression in group-by context (#19993)
  • Fix row_by_key typing (#19888)
📖 Documentation
  • Remove note about guaranteed left join order (#20048)
  • Fix broken links to user guide (#19989)
📦 Build system
  • Pin maturin (#20063)

Thank you to all our contributors for making this release possible! @alexander-beedie, @coastalwhite, @gab23r, @lukemanley, @mcrumiller, @nameexhaustion, @ritchie46, @siddharth-vi, @stijnherfst and @stinodego

View originalPermalink
How 1.16.0 went
1.15.0

Python Polars 1.15.0

Added 3
  • Add AhoCorasick backed 'find_many'
  • Add pl.concat_arr to concatenate columns into an Array column
  • Add rounding for Decimal type
Changed 12
  • Reduce the size of row encoding UTF-8
  • More efficient row encoding for pl.List
  • Half the size of Booleans in row encoding
  • Memoize duplicates in rolling-gb-dyn
  • Rolling 'iter_lookbehind' breeze through duplicates
  • Initially trim leading and trailing filtered rows
Fixed 4
  • Fix Decimal type fill_null
  • Fix panic on schema merge for prefiltering
  • Fix lazy frame join expression
  • Fix gather_every for Scalar
🚀 Performance improvements
  • Reduce the size of row encoding UTF-8 (#19911)
  • Memoize duplicates in rolling-gb-dyn (#19939)
  • More efficient row encoding for pl.List (#19907)
  • Half the size of Booleans in row encoding (#19927)
  • Rolling 'iter_lookbehind' breeze through duplicates (#19922)
  • Initially trim leading and trailing filtered rows (#19850)
✨ Enhancements
  • Catch use of 'polars' in to_string for non-Duration dtypes and raise an informative error (#19977)
  • Add AhoCorasick backed 'find_many' (#19952)
  • Allow Python Enums as dtype inputs (#19926)
  • Speed up starts_with for small prefixes (#19904)
  • Auto-enable hive partitioning if hive_schema was given (#19902)
  • Add pl.concat_arr to concatenate columns into an Array column (#19881)
  • Support both "iso" and "iso:strict" format options for dt.to_string (#19840)
  • Add rounding for Decimal type (#19760)
  • Improved array arithmetic support (#19837)
🐞 Bug fixes
  • Fix Decimal type fill_null (#19981)
  • Fix panic on schema merge for prefiltering (#19972)
  • Fix lazy frame join expression (#19974)
  • Fix gather_every for Scalar (#19964)
  • Toggle 'fast_unique' on new_from_index (#19956)
  • Parse uppercase config keys (#19852)
  • Raise proper error message when too small interval is passed to datetime_range (#19955)
  • Fix scalar object (#19940)
  • Raise InvalidOperationError for invalid float to decimal casts (e.g. Inf, NaN) (#19938)
  • Address indexing edge-case with numpy arrays (#19895)
  • Fix panic with combination of hive and parquet prefiltering (#19905)
  • Fix panic when joining with empty frame (debug only) (#19896)
  • Fix incorrect result from inequality filter after join on LazyFrame (#19898)
  • Misleading ShapeError error message on dataframe creation (#19901)
  • Fix panic with empty delta scan, or empty parquet scan with a provided schema (#19884)
  • Ensure type object of inputs for cached any-value conversion functions are kept alive (#19866)
  • Improve export from 2D Array dtype columns to PyTorch Tensors (to_torch) and Jax Arrays (to_jax) (#19862)
  • Fix panic using scan_parquet().with_row_index() with hive partitioning enabled (#19865)
  • Improve histogram bin logic (#18761)
  • Raise informative error instead of panicking for list arithmetic on some invalid dtypes (#19841)
  • Properly handle Zero-Field Structs in row encoding (#19846)
  • Incorrect explode schema for LazyFrame.explode() (#19860)
  • DataFrame rows_by_key returning key tuples with elements in wrong order (#19486)
  • Ensure List element truncation ellipses respect ASCII* table formats (#19835)
📖 Documentation
  • Remove duplicate sentence in Series.bottom_k docstring (#19947)
  • Complete parameters description and add an example for clip() (#19875)
  • Fix some warnings during docs build (#19848)
📦 Build system
  • Use public windows runners in python release (#19982)
  • Add windows-aarch64 to python binaries (#19966)
🛠️ Other improvements
  • Minor non-breaking space (&nbsp;) tweak for HTML rendering (#19864)
  • Implement nested row encoding / decoding (#19874)
  • Switch back to PyO3 0.22 (#19851)
  • Adjust flaky with_columns test (#19844)
  • Add proper tests for row encoding (#19843)

Thank you to all our contributors for making this release possible! @MarcoGorelli, @alexander-beedie, @barak1412, @coastalwhite, @etiennebacher, @ion-elgreco, @itamarst, @lukemanley, @mcrumiller, @mhogervo, @nameexhaustion, @orlp, @ritchie46, @stijnherfst and @stinodego

View originalPermalink
How 1.15.0 went
1.14.0

Python Polars 1.14.0

Added 3
  • Raise informative error on Unknown unnest
  • Support DataFrame init from raw SQLAlchemy rows
  • Add an is_literal method to expression meta namespace
Changed 4
  • Increase default async thread count for low core count systems
  • Move row group decode off async thread for local streaming parquet scan
  • Support use of Duration in to_string with ergonomic and performance improvements and tz-aware Datetime bugfix
  • A different approach to warning users of fork() issues with Polars
Fixed 14
  • Fix read_database(...,iter_batches=True) type annotations
  • Validate subnodes in validate IR
  • Raise if merge non-global categoricals in unpivot
  • Type hints for window_size incorrectly included timedelta in some rolling functions
  • Don't panic if column not found
  • Fix gather of Scalar null + idx w/ validity
🚀 Performance improvements
  • Increase default async thread count for low core count systems (#19829)
  • Move row group decode off async thread for local streaming parquet scan (#19828)
  • Support use of Duration in to_string, ergonomic/perf improvement, tz-aware Datetime bugfix (#19697)
✨ Enhancements
  • Raise informative error on Unknown unnest (#19830)
  • Support DataFrame init from raw SQLAlchemy rows (#19820)
  • Support use of Duration in to_string, ergonomic/perf improvement, tz-aware Datetime bugfix (#19697)
  • Add an is_literal method to expression meta namespace (#19773)
  • A different approach to warning users of fork() issues with Polars (#19197)
🐞 Bug fixes
  • Fix read_database(…,iter_batches=True) type annotations (#19832)
  • Validate subnodes in validate IR (#19831)
  • Raise if merge non-global categoricals in unpivot (#19826)
  • Type hints for window_size incorrectly included timedelta in some rolling functions (#19827)
  • Don't panic if column not found (#19824)
  • Fix gather of Scalar null + idx w/ validity (#19823)
  • Replace _kwargs in collect method (#19618)
  • Fix object chunked gather (#19811)
  • Fix filter scalar nulls (#19786)
  • Replace spaces with &nbsp; to support showing multiple spaces in HTML repr (#19783)
  • Altair tooltip was being incorrectly applied to plots which did not accept it (#19789)
  • Respect schema_overrides in batched csv reader (#19755)
  • Fix scanning google cloud with service account credentials file (#19782)
  • Release the GIL in Python APIs, part 2 of 2 (#19762)
  • Fix incorrect filter after right-join on LazyFrame (#19775)
  • Fix incorrect lazy schema for explode on array columns (#19776)
  • Fixed typo in file lazy.py (#19769)
📖 Documentation
  • Update bokeh to use cdn to avoid Bokeh Error (#19788)
  • Change dprint config (#19747)
  • Mention row_by_keys in the to_dict documentation (#19767)
  • Fix link to Graphviz download (#19791)
🛠️ Other improvements
  • Add ToField context for common args (#19833)
  • Use polars parquet reader for delta scan (#19103)
  • Migrate polars-expr AggregationContext to use Column (#19736)

Thank you to all our contributors for making this release possible! @MarcoGorelli, @TNieuwdorp, @YichiZhang0613, @alexander-beedie, @braaannigan, @coastalwhite, @engylemure, @gab23r, @iliya-malecki, @ion-elgreco, @itamarst, @jackxxu, @nameexhaustion, @orlp, @ritchie46, @rodrigogiraoserrao and @sn0rkmaiden

View originalPermalink
How 1.14.0 went
1.13.1

Python Polars 1.13.1

Added 1
  • Add IPC source node for new streaming engine
Fixed 3
  • Release GIL in Python APIs, part 1
  • Fix incorrect lazy schema for aggregations
  • Address incorrect selector & col expansion
✨ Enhancements
  • Add IPC source node for new streaming engine (#19454)
🐞 Bug fixes
  • Release GIL in Python APIs, part 1 (#19705)
  • Fix incorrect lazy schema for aggregations (#19753)
  • Address incorrect selector & col expansion (#19742)
📖 Documentation
  • Fix formatting of nested list (#19746)
  • Add meta.is_column to API docs (#19744)
  • Fix join API reference links (#19745)

Thank you to all our contributors for making this release possible! @alexander-beedie, @coastalwhite, @etiennebacher, @itamarst, @nameexhaustion, @orlp, @ritchie46 and @rodrigogiraoserrao

View originalPermalink
How 1.13.1 went
1.13.0

Python Polars 1.13.0

Added 7
  • Try to support native SAP HANA driver via read_database
  • Implement max/min methods for dtypes
  • Identify inefficient use of Python string removeprefix, removesuffix, and zfill in map_elements
  • Identify inefficient use of Python string replace in map_elements
  • Parallel IPC sink for the new streaming engine
  • Add SQL support for RIGHT JOIN and fix an issue with wildcard aliasing
  • Add show_graph to display a GraphViz plot for expressions
Changed 12
  • Improve DataFrame.sort().limit/top_k performance
  • Improve cloud scan performance
  • Improve hive partition pruning with datetime predicates from SQL
  • Allow for arbitrary skips in Parquet Dictionary Decoding
  • Rechunk in DataFrame.rows if needed
  • Dispatch Parquet Primitive PLAIN decoding to faster kernels when possible
Fixed 1
  • Fix quadratic 'with_columns' behavior
🚀 Performance improvements
  • Improve DataFrame.sort().limit/top_k performance (#19731)
  • Improve cloud scan performance (#19728)
  • Fix quadratic 'with_columns' behavior (#19701)
  • Improve hive partition pruning with datetime predicates from SQL (#19680)
  • Allow for arbitrary skips in Parquet Dictionary Decoding (#19649)
  • Reorder conditions in is_leap_year (#19602)
  • Rechunk in DataFrame.rows if needed (#19628)
  • Dispatch Parquet Primitive PLAIN decoding to faster kernels when possible (#19611)
  • Use faster iteration in 'starts_with'/'ends_with' (#19583)
  • Branchless Parquet Prefiltering (#19190)
  • Reduce size of IdxVec from 24 -> 16 bytes (#19550)
✨ Enhancements
  • Try to support native SAP HANA driver via read_database (#19733)
  • Implement max/min methods for dtypes (#19494)
  • Improve n_chunks typing (#19727)
  • Improve hive partition pruning with datetime predicates from SQL (#19680)
  • Identify inefficient use of Python string removeprefix, removesuffix, and zfill in map_elements (#19672)
  • Automatically use boto3 / google-auth if installed when scanning cloud (#19677)
  • Identify inefficient use of Python string replace in map_elements (#19668)
  • Parallel IPC sink for the new streaming engine (#19622)
  • Add SQL support for RIGHT JOIN, fix an issue with wildcard aliasing (#19626)
  • Add show_graph to display a GraphViz plot for expressions (#19365)
  • Streamline use of predicates connected by & with IEJoin (join_where) (#19552)
  • Support use of is_between range predicate with IEJoin operations (join_where) (#19547)
🐞 Bug fixes
  • Use cls for to_python (#19726)
  • Fix validation for inner and left join when join_nulls unflaged (#19698)
  • SQL ELSE clause should be implicitly NULL when omitted (#19714)
  • Improve n_chunks typing (#19727)
  • Ensure NoDataError raised consistently between engines for Excel reads (#19712)
  • In group_by_dynamic, period and every were getting applied in reverse order for the window upper boundary (#19706)
  • Only allow list.to_struct to be elementwise when width is fixed (#19688)
  • Make Array arithmetic ops fully elementwise (#19682)
  • Address inconsistency with use of Python types in frame-level cast (#19657)
  • Update line-splitting logic in batched CSV reader (#19508)
  • Fix incorrect lazy schema for explode() in agg() (#19629)
  • Fix fill null types (#19656)
  • Fix filter incorrectly pushed past struct unnest when unnested column name matches upper column name (#19638)
  • Fix typing for SchemaDefinition (#19647)
  • Ensure mean_horizontal raises on non-numeric input (#19648)
  • Reorder conditions in is_leap_year (#19602)
  • Copy height in .vstack() for empty dataframes (#19641) (#19642)
  • Correct wildcard and input expansion for some more functions (#19588)
  • Allow .struct.with_fields inside list.eval (#19617)
  • Sortedness was incorrectly being preserved in dt.offset_by when offsetting by non-constant durations in the timezone-naive case (#19616)
  • Fix incorrect scan_parquet().with_row_index() with non-zero slice or with streaming collect (#19609)
  • Fix mask and validity confusion in Parquet String decoding (#19614)
  • Parquet decoding of nested dictionary values (#19605)
  • Do not attempt to load default credentials when credential_provider is given (#19589)
  • Fix gather len in group-by state (#19586)
  • Added input validation for explode operation in the array namespace (#19163)
  • Improve error message (#19546)
  • Fix predicate pushdown into inequality joins (#19582)
  • Correct categorical namespace error message (#19558)
  • Fix performance regression for sort/gather on list/array columns (#19564)
  • Ignore quoted newlines when skipping lines in CSV (#19543)
  • Incorrect gather for FixedSizeList with outer validity but no inner validities (#19489)
  • Make Duration parsing fallible and not panic (#19490)
📖 Documentation
  • Revise and rework user-guide/expressions (#19360)
  • Update Excel page of user guide to refer to fastexcel as the default engine (#19691)
  • Alter examples for round_sig_figs to make behaviour clearer (#19667)
  • Assorted fixes to Rust API docs (#19664)
  • Improve replace and replace_all docstring explanation of the "$" character with reference to capture groups (vs use as a literal) (#19529)
  • Add credential provider section and examples to user guide (#19487)
  • Fix various instances of repeated words in docs and comments (#19516)
📦 Build system
  • Bump Rust toolchain to nightly-2024-10-28 (#19492)
🛠️ Other improvements
  • Remove unused Excel code (#19710)
  • Use Column for the {try,}_apply_columns{_par,} functions on DataFrame (#19683)
  • Remove more @scalar-opt (#19666)
  • Move Series bitops to std::ops::Bit... (#19673)
  • Mark test_parquet.py test_dict_slices as slow (#19675)
  • Get Column into polars-expr (#19660)
  • Streamline internal SQL join condition processing (#19658)
  • Factor out logic for re-use by new streaming CSV source (#19637)
  • Configure grouped Dependabot updates (#19604)
  • Fix PyO3 error in CI (#19545)
  • Update nightly compiler version (#19590)
  • Added input validation for explode operation in the array namespace (#19163)
  • Fix lint (#19584)
  • Add a Column::Partitioned variant (#19557)
  • Move to fast-float2 (#19578)
  • Only run remote bench on rust changes (#19581)
  • Remove unsafe *_release functions (#19554)
  • Fix test_rolling_by_integer not using parameterized dtype (#19555)
  • Add mindebug-dev rust profile (#19524)
  • Add CI step to process benchmark results (#19530)
  • Add CI benchmark on merge (#19518)
  • Skip client check with env var (#19517)
  • Improve makefile build commands (#19498)

Thank you to all our contributors for making this release possible! @3tilley, @HansBambel, @MarcoGorelli, @alexander-beedie, @barak1412, @braaannigan, @cmdlineluser, @coastalwhite, @corwinjoy, @dependabot, @dependabot[bot], @eitsupi, @janpipek, @jqnatividad, @letkemann, @max-muoto, @nameexhaustion, @orlp, @ritchie46, @rodrigogiraoserrao, @siddharth-vi, @stinodego and @wence-

View originalPermalink
How 1.13.0 went
1.12.0

Python Polars 1.12.0

Added 4
  • Implement nested Parquet writing for High-Precision Decimals
  • Add credential_provider argument to more read functions
  • Add IPC sink in new streaming engine
  • Support querying specific snapshot by id in scan_iceberg
Changed 5
  • Address inadvertent quadratic behaviour in expand_columns
  • Move rolling_corr/cov to an actual implementation on Series
  • Don't split par if cast to categorical
  • Improve read_database typing
  • Respect include_index for pandas series
Fixed 10
  • Include Array in to_physical
  • Don't panic in SQL temporal string check; raise suitable ColumnNotFound error
  • Properly raise on mean_horizontal with wrong dtypes
  • Make output dtype known for list.to_struct when fields are passed
  • Ensure sorted flag is unset after Int->String cast
  • Fix row_index of batched reader
Deprecated 1
  • Make some parameters of dt.add_business_days keyword-only
⚠️ Deprecations
  • Make some parameters of dt.add_business_days keyword-only (#19428)
🚀 Performance improvements
  • Address inadvertent quadratic behaviour in expand_columns (#19469)
  • Move rolling_corr/cov to an actual implementation on Series (#19466)
  • Don't split par if cast to categorical (#19462)
✨ Enhancements
  • Implement nested Parquet writing for High-Precision Decimals (#19476)
  • Improve read_database typing (#19444)
  • Respect include_index for pandas series (#19453)
  • Add credential_provider argument to more read functions (#19421)
  • Add IPC sink in new streaming engine (#19431)
  • Support querying specific snapshot by id in scan_iceberg (#19388)
🐞 Bug fixes
  • Include Array in to_physical (#19474)
  • Don't panic in SQL temporal string check; raise suitable ColumnNotFound error (#19473)
  • Properly raise on mean_horizontal with wrong dtypes (#19472)
  • Make output dtype known for list.to_struct when fields are passed (#19439)
  • Address inadvertent quadratic behaviour in expand_columns (#19469)
  • Ensure sorted flag is unset after Int->String cast (#19470)
  • Fix row_index of batched reader (#19465)
  • Fix perfect groupby (#19461)
  • Correct wildcard expansion for functions (#19449)
  • Ensure struct eq/ne_missing also compares outer validity (#19443)
  • Fix incorrect reverse on struct containing NULLs (#19446)
  • Faulty escape_regex example (#19440)
  • Capture groups should be ignored in replace when literal=True (#19413)
  • Fix ColumnNotFound when using pl.element() inside list.eval (#19438)
  • Updates error message in csv parser to recommend schema_overrides instead of deprecated dtypes argument (#19416)
  • Incorrect .join(..., how="left").head(N) if N <= left_df.height() and there are duplicate matches (#19422)
  • Support Array type in more DataType methods (#19427)
  • Bug in group_tuples_perfect, tail was not processed properly (#19417)
  • Ensure that ASCII* table formats do not use the UTF8 ellipsis char when truncating rows/cols/values (#19404)
📖 Documentation
  • Fix docstrings for ATAN2 and ATAN2D SQL functions (#19351)
🛠️ Other improvements
  • Undo conflicting fix (#19463)
  • Simplify rust side of datetime (#19459)
  • Add tests for data mismatch on read_json (#19425)
  • Remove code in examples folder in favor of the user guide (#19430)

Thank you to all our contributors for making this release possible! @alexander-beedie, @cmdlineluser, @coastalwhite, @corleyma, @corwinjoy, @dvillaveces, @eitsupi, @gab23r, @janscholten, @nameexhaustion, @orlp, @ritchie46, @siddharth-vi, @stinodego and @wakabame

View originalPermalink
How 1.12.0 went
1.11.0

Python Polars 1.11.0

Added 4
  • AssumeRole support for AWS Credential Provider
  • Added escape_regex operation to the str namespace and as a global function
  • Expose group_by_dynamic in pyir
  • Add AlignedBytes types
Changed 6
  • Improve var/cov/corr performance
  • Reduce memcopy in parquet
  • Optimize array and list gather
  • Various Schema improvements for equality and init dtype checks
  • Improve read_database_uri typing
  • Improve error message for Zero-Field Structs with Parquet
Fixed 8
  • Allow .get(null) in groupby context
  • Fix include_file_paths and with_row_index for streaming CSV scan
  • Release GIL in gather_with_series() and friend
  • Raise on data mismatch in str.json_decode
  • Ensure Python version matches version used to serialize credential provider
  • Capture groups should be ignored in replace_all when literal=True
  • Ignore Parquet is_min_max_value_exact when set to true
  • Projection pushdown was ignored by include_file_paths
🚀 Performance improvements
  • Improve var/cov/corr performance (#19381)
  • Reduce memcopy in parquet (#19350)
  • Optimize array and list gather (#19327)
✨ Enhancements
  • Various Schema improvements (equality/init dtype checks) (#19379)
  • AssumeRole support for AWS Credential Provider (#19346)
  • Added escape_regex operation to the str namespace and as a global function (#19257)
  • Improve read_database_uri typing (#19334)
🐞 Bug fixes
  • Allow .get(null) in groupby context (#19401)
  • Fix include_file_paths and with_row_index for streaming CSV scan (#19394)
  • Flaky parametric parquet test (#19393)
  • Release GIL in gather_with_series() and friend (#19383)
  • Raise on data mismatch in str.json_decode (#19347)
  • Ensure Python version matches version used to serialize credential provider (#19375)
  • Capture groups should be ignored in replace_all when literal=True (#19366)
  • Ignore Parquet is_{min,max}_value_exact when set to true (#19344)
  • Projection pushdown was ignored by include_file_paths (#19341)
📖 Documentation
  • Spurious import in example (#19398)
  • Tiny correction post dask-expr (#19354)
📦 Build system
  • Revert PyO3 version back to 0.21 (#19376)
🛠️ Other improvements
  • Expose group_by_dynamic in pyir (#19385)
  • Add AlignedBytes types (#19308)
  • Remove unsued bytes->BytesIO conversion (#19369)
  • Improve error message for Zero-Field Structs with Parquet (#19370)
  • Reduce memcopy in parquet (#19350)

Thank you to all our contributors for making this release possible! @alexander-beedie, @barak1412, @benrutter, @coastalwhite, @corwinjoy, @itamarst, @max-muoto, @nameexhaustion, @orlp, @ritchie46, @stinodego, @wence- and @wolfgang-noichl

View originalPermalink
How 1.11.0 went
1.10.0

Python Polars 1.10.0

Added 15
  • Add SQL support for bit_count and bitwise &, |, and xor operators
  • Add credential provider utility classes for AWS, GCP
  • Support decoding Float16 in Parquet
  • Experimental credential_provider argument for scan_parquet
  • Allow DeltaTable input to scan_delta and read_delta
  • New quantile interpolation method and QUANTILE_DISC function in SQL
Changed 5
  • Make date_range / datetime_range approximately 10x faster for constant durations
  • Batch utf8-validation in csv with approximately 18% / 25% improvement on 1.9.0
  • Use two-pass algorithm for csv to ensure correctness and SIMDize more with approximately 17% improvement
  • Conserve Parquet SortingColumns for ints
  • Delay deserialization of python function until physical plan
Fixed 1
  • Don't produce duplicate column names in Series.to_dummies
🚀 Performance improvements
  • Add/fix unordered row decode, change unordered format (#19284)
  • Fast decision for Parquet dictionary encoding (#19256)
  • Make date_range / datetime_range ~10x faster for constant durations (#19216)
  • Batch utf8-validation in csv 18% / 25% on 1.9.0 (#19124)
  • Use two-pass algorithm for csv to ensure correctness and SIMDize more ~17% (#19088)
✨ Enhancements
  • Add SQL support for bit_count and bitwise &, |, and xor operators (#19114)
  • Add credential provider utility classes for AWS, GCP (#19297)
  • Support decoding Float16 in Parquet (#19278)
  • Experimental credential_provider argument for scan_parquet (#19271)
  • Allow DeltaTable input to scan_delta and read_delta (#19229)
  • New quantile interpolation method & QUANTILE_DISC function in SQL (#19139)
  • Conserve Parquet SortingColumns for ints (#19251)
  • Low level flight interface (#19239)
  • Improved list arithmetic support (#19162)
  • Add Expr.struct.unnest() as alias for Expr.struct.field("*") (#19212)
  • Add 'drop_empty_rows' parameter for read_ods (#19202)
  • Add 'drop_empty_rows' parameter for read_excel (#18253)
  • Expose LTS CPU in show_versions() (#19193)
  • Check Python version when deserializing UDFs (#19175)
  • Raise an error when users try to use Polars API in a fork()-without-execve() child (#19149)
  • Quantile function in SQL (#18047)
  • Improve scalar strict message (#19117)
  • Add Series::{first, last, approx_n_unique} (#19093)
  • Allow for rolling_*_by to use index count as window (#19071)
  • Delay deserialization of python function until physical plan (#19069)
  • Add cum(_min/_max) for pl.Boolean (#19061)
🐞 Bug fixes
  • Don't produce duplicate column names in Series.to_dummies (#19326)
  • Use of HAVING outside of GROUP BY should raise a suitable SQLSyntaxError (#19320)
  • More accurate from_dicts typing/signature (#19322)
  • Fix empty array gather (#19316)
  • Merge categorical rev-map in unpivot (#19313)
  • DataFrame descending sorting by single list element (#19233)
  • Fix cse union schema (#19305)
  • Correctly load Parquet statistics for f16 (#19296)
  • Error on invalid query (#19303)
  • Fix enum scalar output (#19301)
  • Fix list gather invalid fast path (#19299)
  • Fix quoting style of decimal csv output (#19298)
  • Don't vertically parallelize literal select (#19295)
  • Fix struct reshape fast path (#19294)
  • Also split on forward slashes during hive path inference on Windows (#19282)
  • Don't cse as_struct (#19280)
  • Only apply string parsing to String dtype (#19222)
  • Make the SQLAlchemy connection check more robust (#19270)
  • Ensure that read_database takes advantage of Arrow return from a duckdb_engine connection when using a SQLAlchemy Selectable (#19255)
  • Compilation error missing use JsonLineReader (#19244)
  • Don't remember Parquet statistics if filtered (#19248)
  • Do not check dtypes of non-projected columns for parquet (#19254)
  • Parquet predicate pushdown for lit(_) != (#19246)
  • Use all chunks in Series from arrow struct (#19218)
  • Don't trigger row limit in array construction (#19215)
  • Fix struct literals (#19214)
  • Plotting was not interacting well with Altair schema wrappers (#19213)
  • Fixing infer_schema for DataType::Null (#19201)
  • Migrate to PyO3 0.22 and released verion of rust-numpy crate (#19199)
  • Add 'drop_empty_rows' parameter for read_excel (#18253)
  • Don't unwrap() expansion (#19196)
  • Properly handle non-nullable nested Parquet (#19192)
  • Fix invalid list collection in expression engine (#19191)
  • Fix use of "hidden_columns" parameter in write_excel (#19029)
  • Implement to_arrow functionality properly for Arrays (#19077)
  • Remove incorrect warning when using an IO[bytes] instance (#19154)
  • Don't fail test if e.g. jax has been used first, since jax installs a fork handler that warns (#19178)
  • Fix incorrect (eq|ne)_missing on List/Array types (#19155)
  • Properly broadcast Struct when then validity (#19148)
  • Allow partial name overlap in join_where resolution (#19128)
  • Fix floordiv / modulo with scalar 0 on LHS (#19143)
  • Ensure aligned chunks in OOC sort (#19118)
  • Recursively align when converting to ArrowArray (#19097)
  • Raise on invalid shape of shape 1, empty combination (#19113)
  • Use two-pass algorithm for csv to ensure correctness and SIMDize more ~17% (#19088)
  • Allow converting DatetimeOwned to ChunkedArray (#19094)
  • Throw proper error for empty char params in scan_csv (#19100)
  • Ensure parquet schema arg is propagated to IR (#19084)
  • Only rewrite numeric ineq joins (#19083)
  • Check validity of columns of keys/aggs in dsl->ir (#19082)
  • Bitwise aggregations should ignore null values (#19067)
  • Remove failing datetime subclass test (#19068)
  • Don't ignore multiple columns in LazyFrame.unnest (#19035)
📖 Documentation
  • Remove ecosystem viz section since there is one in misc already (#18408)
  • Fix typo in custom expressions docs (#19292)
  • Add SQL docs for new QUANTILE_CONT and QUANTILE_DISC functions (#19272)
  • Add marimo to ecosystem.md (#19250)
  • Improve DataFrame.write_database docstring (#19189)
  • Link to main website from banner (#19177)
  • Fix example of as_struct (#19116)
  • Clarify difference between bitwise/logical ops (#19180)
  • Add non-equi joins to, and revise, joins docs page (#19127)
  • Add Series.first,last,approx_n_unique to docs (#19146)
  • Annotate Config kwarg options (#18988)
  • Revise and improve 'Concepts' section (#19087)
🛠️ Other improvements
  • Add/fix unordered row decode, change unordered format (#19284)
  • Move from parquet-format-safe to polars-parquet-format (#19275)
  • Skip flaky test (#19242)
  • Add more tests for list arithmetic (#19225)
  • Remove unused IPC async (#19223)
  • Make get_list_builder infallible (#19217)
  • Migrate to PyO3 0.22 and released verion of rust-numpy crate (#19199)
  • Make expression output type known (#19195)
  • Revert "feat(python): Raise an error when users try to use Polars API in a fork()-without-execve() child (#19149) (#19188)
  • Zero-Field Structs and DataFrame with Height Property (#19123)
  • Make pl.repeat part of the IR (#19152)
  • Expose IEJoin IR node to python (#19104)
  • Clean remove_prefix since python3.9 is now the minimum Python (#19070)
  • Add new streaming engine to CI (#19051)

Thank you to all our contributors for making this release possible! @Bidek56, @MarcoGorelli, @Rashik-raj, @adamreeve, @alexander-beedie, @alonme, @balbok0, @coastalwhite, @deanm0000, @dependabot, @dependabot[bot], @eitsupi, @etrotta, @itamarst, @jbutterwick, @joelostblom, @kenkoooo, @khalidmammadov, @laurentS, @mcrumiller, @mscolnick, @nameexhaustion, @orlp, @pomo-mondreganto, @ritchie46, @rodrigogiraoserrao, @siddharth-vi, @stinodego, @sunadase and @wence-

View originalPermalink
How 1.10.0 went
1.9.0

Python Polars 1.9.0

Added 7
  • Add bitwise operations and aggregations
  • Allow `insert_column` to take expressions
  • Add `strict` param to eager/lazy frame rename
  • Support `schema` arg in `read/scan_parquet()`
  • Add `include_file_paths` parameter to `read_parquet`
  • Add `allow_missing_columns` option to `read/scan_parquet`
  • Allow for zero-width fixed size lists
Changed 6
  • Use List's TotalEqKernel for performance improvement
  • Improved error message DSL to IR resolving
  • Drop Python 3.8 support
  • Use FFI to extract Series from different Polars binaries
  • Bump Rust toolchain to nightly-2024-09-29
  • Bump `simd-json` to 0.14
Fixed 7
  • Fix divide-by-zero in OOC sort
  • Ensure `must_flush` flag is not reset
  • Fix invalid alias udf
  • Return the truth values of `ne_missing` and `eq_missing` operations for struct instead of `null`
  • Fix list to numpy conversion
  • Fix struct broadcasting comparisons
  • Fix `Expr.over` with `order_by` did not take effect if group keys were sorted
🚀 Performance improvements
  • Use List's TotalEqKernel (#18984)
✨ Enhancements
  • Bitwise operations / aggregations (#18994)
  • Allow insert_column to take expressions (#19024)
  • Improved error message DSL -> IR resolving (#19032)
  • Add strict param to eager/lazy frame "rename" (#19017)
  • Support schema arg in read/scan_parquet() (#19013)
  • Add include_file_paths parameter to read_parquet (#19008)
  • Add allow_missing_columns option to read/scan_parquet (#18922)
  • Drop python 3.8 support (#18965)
  • Use FFI to extract Series from different Polars binaries (#18964)
  • Allow for zero-width fixed size lists (#18940)
🐞 Bug fixes
  • Remove failing temporal lit tests (#19056)
  • Divide-by-zero in OOC sort (#19048)
  • Ensure must_flush flag is not reset (#19046)
  • Error node should be on top (#19045)
  • Force nested struct missing equality (#19031)
  • Fix invalid alias udf (#19021)
  • Raise invalid predicate join_where (#19020)
  • Fix nested flag of functions with multiple arguments (#19016)
  • Fix projection pushdown bug in IEJOINS (#19015)
  • Separate temporal tests (#19012)
  • Return the truth values of ne_missing and eq_missing operations for struct instead of null (#18930)
  • Fix list to numpy conversion (#19009)
  • Fix struct broadcasting comparisons (#19003)
  • Wrong result on when().then().otherwise() on struct when both result are broadcast (#19000)
  • Improve literals for temporal subclasses (#18998)
  • Ensure same fmt in Series/AnyValue to string cast (#18982)
  • Return correct value for when().then().else() on structs when using first()\last() (#18969)
  • IPC don't write variadic_buffer_counts in blocks, but only dictionaries (#18980)
  • Respect allow_threading in TernaryExpr (#18977)
  • Make join test order-agnostic (#18975)
  • Fix lit().shrink_dtype() broadcasting (#18958)
  • Parallel evaluation of cumulative_eval (#18959)
  • Properly implement AnyValue::Binary into_py (#18960)
  • Fix Expr.over with order_by did not take effect if group keys were sorted (#18947)
  • Properly fetch type of full None List Series (#18916)
  • Incorrect mode for sorted input (#18945)
  • Properly choose inner physical type for Array (#18942)
  • Disable very old date in timezone test for CI (#18935)
  • Infer reshape dims when determining schema (#18923)
  • Incorrect broadcasting on list-of-string set ops (#18918)
  • Adding with_row_index() to previously collected lazy scan does not take effect (#18913)
📖 Documentation
  • Fix example of lazy schema verification (#19059)
  • Rewrite 'Getting started' page (#19028)
  • Fix is_not_nan description (#18985)
  • Recommend targetDir for rust-analyzer (#18973)
  • Fix LazyFrame fetch method references (#18033)
📦 Build system
  • Bump Rust toolchain to nightly-2024-09-29 (#19006)
  • Bump simd-json to 0.14 (#18999)
🛠️ Other improvements
  • Remove built info (#19057)
  • Mark schema arg in read/scan_parquet as unstable (#19018)
  • Fix new-streaming test_lazy_parquet::test_row_index (#19019)
  • Preserve scalar in more places (#18898)
  • Mention allow_missing_columns in error message when column not found (parquet) (#18972)
  • Disable CSE-specific test on new streaming engine (#18971)
  • Add FixedSizeList equality broadcasting (#18967)
  • Divide ChunkCompare into Eq and Ineq variants (#18963)
  • Another set of new-stream test skip/fixes (#18952)
  • Fix/skip variety of new-streaming tests, cont (#18928)
  • Fix/skip variety of new-streaming tests (#18924)

Thank you to all our contributors for making this release possible! @LukasFolwarczny, @Plutone11011, @aleexharris, @alexander-beedie, @barak1412, @coastalwhite, @dependabot, @dependabot[bot], @edwinvehmaanpera, @kgv, @mcrumiller, @nameexhaustion, @orlp, @ritchie46, @rodrigogiraoserrao, @stinodego and @xhiroga

View originalPermalink
How 1.9.0 went
1.8.2

Python Polars 1.8.2

Changed 3
  • Improve rename performance for Lazy API
  • Collapse cross-joins to faster joins
  • Improve scalar strict message
Fixed 6
  • Properly zip struct validities
  • Fix out-of-bounds gather in categorical to int cast
  • Fix AnyValue Series from Categorical/Enum
  • Properly cast AnyValue string
  • Fix stack overflow in JSON inference
  • Use proper thread pool in cumulative_eval
🚀 Performance improvements
  • Improve rename performace for Lazy API (#18890)
  • Collapse cross-joins to faster joins (#18633)
✨ Enhancements
  • Improve scalar strict message (#18904)
🐞 Bug fixes
  • Properly zip struct validities (#18886)
  • Out-of-bounds gather in categorical->int cast (#18897)
  • AnyValue Series from Categorical/Enum (#18893)
  • Properly cast AnyValue string (#18888)
  • Fix SO in json inference (#18887)
  • Use proper thread pool in cumulative_eval (#18885)
📖 Documentation
  • Fix broken user-guide API links (#18872)

Thank you to all our contributors for making this release possible! @coastalwhite, @npielawski, @orlp, @ritchie46 and @siddharth-vi

View originalPermalink
How 1.8.2 went
1.8.1

Python Polars 1.8.1

Changed 3
  • Cache register plugin function
  • Make with_column_unchecked take Column
  • Keep scalar in more places
Fixed 4
  • Properly calculate duration units
  • Check values in strict cast Int to Time
  • Fix typo in DuplicateError error message
  • Properly merge live- and dead columns in prefiltered
🚀 Performance improvements
  • Cache register plugin function (#18860)
🐞 Bug fixes
  • Properly calculate duration units (#18869)
  • Check values in strict cast Int to Time (#18854)
  • Fix typo in DuplicateError error message (#18855)
  • Properly merge live- and dead columns in prefiltered (#18862)
📖 Documentation
  • Fix minor rogue apostrophes (#18865)
🛠️ Other improvements
  • Make with_column_unchecked take Column (#18863)
  • Keep scalar in more places (#18775)

Thank you to all our contributors for making this release possible! @MarcoGorelli, @coastalwhite, @mcrumiller, @ritchie46 and @rodrigogiraoserrao

View originalPermalink
How 1.8.1 went
1.8.0

Python Polars 1.8.0

Added 1
  • Support arithmetic between Series with dtype list
Changed 3
  • Relax schema alignment for parquet file list read
  • Always preserve sorted flag for .dt.date
  • Implement single inequality joins for join_where
Fixed 15
  • DataFrame plot was raising when some extra keywords were passed to encodings
  • Respect strictness in list constructor
  • Properly broadcast array arithmetic
  • Throw error for comparison of unequal length series
  • Raise when parquet file has extra columns and no select() was done
  • Pass missing user params in write_csv
✨ Enhancements
  • Support arithmetic between Series with dtype list (#17823)
  • Relaxed schema alignment for parquet file list read (#18803)
  • Always preserve sorted flag for .dt.date (#18692)
  • Enable additional ruff lint rule sets (#18721)
  • Implement single inequality joins for join_where (#18727)
🐞 Bug fixes
  • DataFrame plot was raising when some extra keywords were passed to encodings (e.g. x=alt.X(a, axis=alt.Axis(labelAngle=30))) (#18836)
  • Respect strictness in list constructor (#18853)
  • Properly broadcast array arithmetic (#18851)
  • Throw error for comparison of unequal length series (#18816)
  • Raise when parquet file has extra columns and no select() was done (#18843)
  • Pass missing user params in write_csv (#18845)
  • Improve join argument checks (#18847)
  • Struct filter by index (#18778)
  • Proper dtype casting for struct embedded categoricals in chunked categoricals (#18815)
  • Fixed some error/assertion types (#18811)
  • Remove panic in arr.to_struct (#18804)
  • Allow empty sort by columns (#18774)
  • Broadcast zip_with for structs (#18770)
  • Dropped/shifted rows in parquet scan with streaming=True (#18766)
  • Fix cum_max using exception text of cum_min for invalid dtype (#18780)
  • Fix accidental raise on shape 1 (#18748)
📖 Documentation
  • Fix link to issue tracker and code snippet format in GPU docs (#18850)
  • Clarify documentation for schema in read_csv function (#18759)
  • Fix literal type mapping example in lit docstrings (#18756)
  • Refactor docs directory hierarchy (#18773)
  • Minor improvements to contributing guide (#18777)
  • Improve over docs, add example with order_by (#18796)
  • Add documentation for beta gpu support (#18762)
🛠️ Other improvements
  • Re-export PyO3 in polars-python crate (#18835)
  • Make NodeTraverser struct public (#18822)
  • Add panic to unchecked DataFrame constructors in debug mode (#18807)
  • Fix parquet file metadata is dropped after first DSL->IR conversion (#18789)
  • Remove extra hashmap construction in new-streaming parquet (#18792)
  • Remove TODO comment regarding NumPy pinning (#18776)
  • Remove unused methods (#18744)
  • Make DataFrame a Vec of Column instead of Series (#18664)
  • Run benchmark on PR labeled 'needs-bench' (#18737)
  • Enable additional ruff lint rule sets (#18721)

Thank you to all our contributors for making this release possible! @3ok, @Manishearth, @MarcoGorelli, @adamreeve, @alexander-beedie, @barak1412, @beckernick, @bradfordlynch, @coastalwhite, @deanm0000, @eitsupi, @i64, @itamarst, @mcrumiller, @nameexhaustion, @orlp, @r-brink, @ritchie46, @rodrigogiraoserrao, @squnit, @stinodego and @t-ded

View originalPermalink
How 1.8.0 went
1.7.1

Python Polars 1.7.1

Changed 1
  • Remove IR info from DSL
Fixed 3
  • Revert automatically turning on Parquet prefiltered
  • Parquet prefiltered with projection pushdown
  • Fix scalar literals
Removed 2
  • Remove unused feature flags from polars-mem-engine
  • Remove hive_parts from DSL source
🐞 Bug fixes
  • Revert automatically turning on Parquet prefiltered (#18720)
  • Parquet prefiltered with projection pushdown (#18714)
  • Fix scalar literals (#18707)
🛠️ Other improvements
  • Remove IR info from DSL (#18712)
  • Remove unused feature flags from polars-mem-engine (#18679)
  • Remove hive_parts from DSL source (#18694)

Thank you to all our contributors for making this release possible! @ankane, @attila-lin, @coastalwhite, @eitsupi, @nameexhaustion, @orlp and @ritchie46

View originalPermalink
How 1.7.1 went
1.7.0

Python Polars 1.7.0

Added 6
  • Support IO[bytes] and bytes in scan_{...} functions
  • IEJoin algorithm for non-equi joins and support for Full non-equi joins
  • Optimizer rules for is_null().all() and similar expressions to use null_count()
  • Tooltip by default to charts
  • Support for shortcut eval of common boolean filters in SQL interface WHERE clause
  • Make expressions containing Python UDFs serializable
Changed 5
  • Back arrow arrays with SharedStorage which can have non-refcounted static slices
  • PlSmallStr implementation from Arc<str> to compact_str
  • Enable Parquet parallel=prefiltered for auto
  • BytecodeParser for upcoming Python 3.13
  • join_where semantics
Fixed 9
  • Use IO[bytes] instead of BytesIO in DataFrame.write_parquet()
  • Scalar checks
  • Scanning hive partitioned files where hive columns are partially included in the file
  • Use Buffer<T> in ObjectSeries, fixes variety of offset bugs
  • Properly slice validity mask on pl.Object series
  • Raise if single argument form in replace/replace_strict is not a mapping
🏆 Highlights
  • Add support for IO[bytes] and bytes in scan_{...} functions (#18532)
  • Add IEJoin algorithm for non-equi joins and support Full non-equi joins (#18365)
🚀 Performance improvements
  • Back arrow arrays with SharedStorage which can have non-refcounted static slices (#18666)
  • Don't traverse file list twice for extension validation (#18620)
  • Remove cloning of ColumnChunkMetadata (#18615)
  • Add upfront partitioning in ColumnChunkMetadata (#18584)
  • Enable Parquet parallel=prefiltered for auto (#18514)
  • Change PlSmallStr impl from Arc<str> to compact_str (#18508)
  • Added optimizer rules for is_null().all() and similar expressions to use null_count() (#18359)
✨ Enhancements
  • Update BytecodeParser for upcoming Python 3.13 (#18677)
  • Add tooltip by default to charts (#18625)
  • Add support for IO[bytes] and bytes in scan_{...} functions (#18532)
  • Support shortcut eval of common boolean filters in SQL interface "WHERE" clause (#18571)
  • Add IEJoin algorithm for non-equi joins and support Full non-equi joins (#18365)
  • Make expressions containing Python UDFs serializable (#18135)
🐞 Bug fixes
  • Use IO[bytes] instead of BytesIO in DataFrame.write_parquet() (#18652)
  • Scalar checks (#18627)
  • Scanning hive partitioned files where hive columns are partially included in the file (#18626)
  • Enable "polars-json/timezones" feature from "polars-io" (#18635)
  • Use Buffer<T> in ObjectSeries, fixes variety of offset bugs (#18637)
  • Properly slice validity mask on pl.Object series (#18631)
  • Raise if single argument form in replace/replace_strict is not a mapping (#18492)
  • Fix group first value after group-by slice (#18603)
  • Allow for date/datetime subclasses (e.g. pd.Timestamp, FreezeGun) in pl.lit (#18497)
  • Fix output type for list.eval in certain cases (#18570)
  • Fix map_elements for List return dtypes (#18567)
  • Check for duplicate column names in read_database cursor result, raising DuplicateError if found (#18548)
  • Do not remove double-sort if maintain_order=True (#18561)
  • Empty any_horizontal should be false, not true (#18545)
  • Fix type inference error in map_elements for List types (#18542)
  • Address incorrect align_frames result when the alignment column contains NULL values (#18521)
  • Fix advertised version in source builds (#18523)
  • Handle Parquet projection pushdown with only row index (#18520)
  • DataFrame write_database not passing down "engine_options" when using ADBC (#18451)
  • Properly raise on invalid selector expressions (#18511)
  • Wrong output column name in or and xor operations (#18512)
  • Normalize by default in Series.entropy like Expr.entropy does (#18493)
  • Various schema corrections (#18474)
  • Don't drop objects on empty buffers (#18469)
  • Expr.sign should preserve dtype (#18446)
  • Ensure assert_frame_not_equal and assert_series_not_equal raise on mismatched input types (#18402)
  • Fixed Worksheet definition in write_excel type annotations (#18452)
📖 Documentation
  • Update join_where docs to clarify behaviour (#18670)
  • Fix multiprocessing docs regarding fork method check (#18563)
  • Various docstring improvements to testing.assert_* functions (#18494)
  • Fix formula in ewm_mean_by (#18506)
  • Pre-compute plugin_path before defining plugin (#18503)
  • Add Expr.null_count to aggregations (#18459)
🛠️ Other improvements
  • Fix a bunch of tests for new-streaming (#18659)
  • Don't raise on multiple same names in ie_join (#18658)
  • Check predicates in join_where (#18648)
  • Change join_where semantics (#18640)
  • Add benchmark tests for join_where with inequalities (#18614)
  • Check number of binary comparisons in join_where predicates (#18608)
  • Raise on suffixed predicate in join_where (#18607)
  • Fix Python docs build (#18605)
  • Use streaming argument in test_parquet_slice_pushdown_non_zero_offset (#18529)
  • Fix delta test merge (#18601)
  • Alter/skip some tests for new streaming (#18574)
  • Add lower-bound pin for numba (#18555)
  • Temporarily pin NumPy in CI to address dependency resolving issue (#18544)
  • Change PlSmallStr impl from Arc<str> to compact_str (#18508)
  • Make expressions containing Python UDFs serializable (#18135)
  • Change naming to new benchmark setup (#18473)
  • Ensure physical arguments to np ufuncs are rechunked (#18471)
  • Remove a string allocation in Parquet (#18466)
  • Remove network call in hf docs (#18454)

Thank you to all our contributors for making this release possible! @0xbe7a, @MarcoGorelli, @WbaN314, @adamreeve, @alexander-beedie, @alonme, @barak1412, @coastalwhite, @dependabot, @dependabot[bot], @eitsupi, @henryharbeck, @ion-elgreco, @krasnobaev, @megaserg, @nameexhaustion, @ohanf, @orlp, @philss, @r-brink, @ritchie46, @skellys, @squnit, @stinodego, @wence- and @yarimiz

View originalPermalink
How 1.7.0 went
1.6.0

Python Polars 1.6.0

Added 3
  • Add POLARS_BACKTRACE_IN_ERR for debugging
  • IR serde
  • Support empty structs
Changed 8
  • Use Altair in DataFrame.plot
  • Allow mapping as syntactic sugar in str.replace_many
  • Respect input time zone if input is pandas Timestamp
  • Improve Schema and DataType interop with Python types
  • Support pre-signed URLs for cloud scan
  • Support the most recent version of duckdb_engine connections via read_database
  • Allow float in interpolate_by by column
  • Make show_versions more responsive
Fixed 8
  • Enable CSE in eager if struct are expanded
  • Treat explode as gather
  • Parquet nested values that span several pages
  • Support reading empty parquet files
  • Recurse on map field during type conversion
  • Allow search_sorted on boolean series
  • Mark Expr.lower_bound and Expr.upper_bound as returning scalar
  • Fix compressed ndjson row count
💥 Unstable Breaking changes

These API's were marked unstable and are allowed to change.

  • Use Altair in DataFrame.plot (#17995)
🚀 Performance improvements
  • Parquet do not copy uncompressed pages (#18441)
  • Several large parquet optimizations (#18437)
  • Batch Plain Parquet UTF-8 verification (#18397)
  • Partition metadata for parquet statistic loading (#18343)
  • Fix accidental quadratic parquet metadata (#18327)
  • Lazy decompress Parquet pages (#18326)
  • Don't rechunk aligned chunks in owned_binary_chunk_align (#18314)
  • Batch DELTA_LENGTH_BYTE_ARRAY decoding (#18299)
  • Slice pushdown for SimpleProjection (#18296)
  • Use direct path for time/timedelta literals (#18223)
  • Speedup ndjson reader ~40% (#18197)
  • Skip parquet page when unneeded (#18192)
✨ Enhancements
  • Use Altair in DataFrame.plot (#17995)
  • Allow mapping as syntactic sugar in str.replace_many (#18214)
  • Respect input time zone if input is pandas Timestamp (#18346)
  • Improve Schema and DataType interop with Python types (#18308)
  • Add POLARS_BACKTRACE_IN_ERR for debugging (#18333)
  • IR serde (#18298)
  • Improve decimal_comma error message (#18269)
  • Support pre-signed URLs for cloud scan (#18274)
  • Support the most recent version of "duckdb_engine" connections via read_database (#18277)
  • Support empty structs (#18249)
  • Allow float in interpolate_by by column (#18015)
  • Make show_versions more responsive (#18208)
🐞 Bug fixes
  • Enable CSE in eager if struct are expanded (#18426)
  • Treat explode as gather (#18431)
  • Parquet nested values that span several pages (#18407)
  • Support reading empty parquet files (#18392)
  • Recurse on map field during type conversion (#15075)
  • Allow search_sorted on boolean series (#18387)
  • Mark Expr.(lower|upper)_bound as returning scalar (#18383)
  • Fix compressed ndjson row count (#18371)
  • Use correct column names when there are no value columns in unpivot (#18340)
  • Parquet several smaller issues (#18325)
  • Fix group-by slice on all keys (#18324)
  • Compute joint null mask before calling rolling corr/cov stats (#18246)
  • Several scan_parquet(parallel='prefiltered') problems (#18278)
  • Json feature flag missing imports (#18305)
  • Check groups in group-by filter (#18300)
  • Parquet delta encoding for 0-bitwidth miniblocks (#18289)
  • Arguments for upsample only have to be sorted within groups (#18264)
  • Use appropriate bins in hist when bin_count specified (#16942)
  • Raise suitable error on unsupported SQL set op syntax (#18205)
  • Fix invalid state due to cached IR (#18262)
  • Fix failed AWS credential load from '~/.aws/credentials' due to formatting (#18259)
  • Fix panic streaming parquet scan from cloud with slice (#18202)
  • Consistently round half-way points down in dt.round (#18245)
  • Fix duplicate column output and panic for include_file_paths (#18255)
  • Fix unit null rank (#18252)
  • Use physical for row-encoding (#18251)
  • Convert date and datetime in literal construction (#16018)
  • Fix gather str as lit (#18207)
📖 Documentation
  • Add date_range and datetime_ranges examples without eager=True (#18379)
  • Fix incorrect comments in group_by_dynamic (#18415)
  • Alphabetise methods in Python API reference (#18380)
  • Document POLARS_BACKTRACE_IN_ERR env var (#18354)
  • Add missing aggregation entries (#18334) (#18341)
  • Add missing Series methods to API reference (#18312)
  • Document DataFrame.__getitem__ and Series.__getitem__ (#18309)
  • Fix typos and add see also links to struct name expressions (#18282)
  • Improve decimal_comma error message (#18269)
  • Clarify coalesce behaviour in join_asof (#18273)
  • Add note to Expr.shuffle differentiating from df method (#18266)
  • Improve formatting and consistency of various docstrings (#18237)
  • Add missing "Parameters" section to bin.size expr docstring (#18222)
  • Fix column name output in example of DataFrame.map_rows (#18227)
📦 Build system
  • Bump Rust toolchain to nightly-2024-08-26 (#18370)
🛠️ Other improvements
  • Address spurious hypothesis test failure (#18434)
  • Turn all Binary/Utf8 into BinaryView/Utf8View in Parquet (#18331)
  • Fix the required version of rust in README.md (#18357)
  • Remove unused Parquet indexes (#18329)
  • Deprecate serialize json for LazyFrame (#18283)
  • Don't add sink node to cloud query (#18280)
  • Split py-polars crate (#18204)
  • Fix test for new deltalake release (#18211)
  • Update the required version of rust in README.md (#18203)
  • Fix version bifurcation for test_read_database_cx_credentials (#18220)
  • Use or_else for raising (#18206)
  • Remove unused Parquet source files (#18193)

Thank you to all our contributors for making this release possible! @BartSchuurmans, @ChayimFriedman2, @MarcoGorelli, @StepfenShawn, @agossard, @alexander-beedie, @cgbur, @coastalwhite, @corwinjoy, @deanm0000, @henryharbeck, @ion-elgreco, @jqnatividad, @krasnobaev, @liufeimath, @markxwang, @mcrumiller, @nameexhaustion, @orlp, @ritchie46, @stinodego, @sunadase, @thomascamminady and @wence-

View originalPermalink
How 1.6.0 went
1.5.0

Python Polars 1.5.0

Added 2
  • Create literals for datetime/date expressions
  • Expose top-level has_header param for read_excel and read_ods
Changed 12
  • Improve binview extend/ifthenelse performance
  • Start on better Parquet delta decoding
  • Rechunk group-by __iter__
  • Tune jemalloc to not create muzzy pages
  • Reduce default async thread count
  • Make expensive selector expansion lazy
Fixed 5
  • Fix struct shift and list builder
  • Don't load Parquet nested metadata
  • Throw bigidx error for Parquet row-count
  • Fix unpivot on empty df
  • Ensure default values are included when saving/restoring the current Config state
🚀 Performance improvements
  • Improve binview extend/ifthenelse (#18164)
  • Start on better Parquet delta decoding (#18049)
  • Rechunk group-by __iter__ (#18162)
  • Tune jemalloc to not create muzzy pages (#18148)
  • Reduce default async thread count (#18142)
  • Make expensive selector expansion lazy (#18118)
  • Use single threaded algorithms if only 1 core given (#18101)
  • Use Arc<Vec<_>> instead of Arc<[_]> for paths and hive partitions (#18066)
  • SIMD View from FixedSizeBinary (#18059)
  • Use bitmask to filter Parquet predicate-pushdown items (#17993)
  • Zerocopy buffers for FixedSizeBinary to BinaryView cast (#18043)
✨ Enhancements
  • Create literals for datetime/date expressions (#18184)
  • Create literals in 'datetime' expression (#18182)
  • Expose top-level "has_header" param for read_excel and read_ods (#18078)
  • Raise on invalid 'is_between' and improve error message quality (#18147)
🐞 Bug fixes
  • Fix struct shift and list builder (#18189)
  • Don't load Parquet nested metadata (#18183)
  • Throw bigidx error for Parquet row-count (#18154)
  • Fix unpivot on empty df (#18179)
  • Don't vertically parallelize cse contexts (#18177)
  • Ensure default values are included when saving/restoring the current Config state (#18151)
  • Properly handle empty Parquet row groups with no dictionary (#18161)
  • Struct outer nullabillity (#18156)
  • Fix pyarrow predicate pushdown regression (#18145)
  • Prevent unwanted supertype cast in 'search_sorted' (#18143)
  • Parquet with filter=None (#18139)
  • Don't raise when converting from pandas if index contains duplicate names when include_index=False (the default) (#18133)
  • Fix cast Float to String where Float is not turn to Integer before turning to String (#18123)
  • Don't remove leading whitespace in read_csv (#18131)
  • Py-polars compilation with no features (#18129)
  • String transform to_titlecase was too narrowly defined (#18122)
  • Reading Parquet with Null dictionary page (#18112)
  • When setting write_excel column totals, don't forget to include any row-total cols (#18042)
  • Incorrect lazy CSV select(len()) for compressed files (#18067)
  • Fix sink_ipc_cloud panicking with runtime error (#18091)
  • Properly write Parquet for sliced lists (#18073)
  • Panic reading multiple CSV files from cloud (#18056)
  • Fix CloudWriter to use buffer before making requests (#18027)
  • Fix typos and remove trailing whitespace (#18024)
  • Handle cfg(feature) for shrink_dtype (#18038)
📖 Documentation
  • Fix references to old methods in lazy docstring (#18178)
  • Include PyCapsule Interface in DataFrame and Series API docs (#18174)
  • Corrected example result in group_by docs (#18169)
  • Mention 'Array' in data types overview (#18060)
  • Correct concat rechunk in user guide (#18080)
  • Fix typo in title of Hugging Face docs page (#18097)
  • Update pivot docstring for clarity (#18000)
🛠️ Other improvements
  • Remove unneeded growable (#18165)
  • Update Cargo.lock to fix build error on Linux (#18153)
  • Remove Nth,Wildcard from ExprIR and make conversion falllible (#18115)

Thank you to all our contributors for making this release possible! @EricTulowetzke, @KDruzhkin, @MarcoGorelli, @Vincenthays, @alexander-beedie, @coastalwhite, @davanstrien, @deanm0000, @ember91, @kylebarron, @mcrumiller, @nameexhaustion, @orlp, @philss, @ritchie46 and @rosstitmarsh

View originalPermalink
How 1.5.0 went
1.4.1

Python Polars 1.4.1

Added 2
  • Add boolean Parquet HybridRle encoding
  • Support passing Worksheet objects to the write_excel method
Changed 3
  • Improve integer fast path Parquet dict encoding
  • Speed up writing of Parquet primitive values
  • Remove temporary allocations in Parquet
Fixed 2
  • Fix subtraction with overflow on negative slice offset in Parquet
  • Fix drop selector
🚀 Performance improvements
  • Integer fast path Parquet dict encoding (#18030)
  • Speedup writing of Parquet primitive values (#18020)
  • Remove temporary allocations in Parquet (#18013)
✨ Enhancements
  • Add boolean Parquet HybridRle encoding (#18022)
  • Support passing Worksheet objects to the write_excel method (#18031)
🐞 Bug fixes
  • Subtraction with overflow on negative slice offset in Parquet (#18036)
  • Fix drop selector (#18034)
📖 Documentation
  • Update map_batches docstring (#18001)
🛠️ Other improvements
  • Add @coastalwhite to parquet codeowners (#18032)
  • Minor bump to comfy-table version (#18028)

Thank you to all our contributors for making this release possible! @alexander-beedie, @coastalwhite, @deanm0000, @nameexhaustion and @ritchie46

View originalPermalink
How 1.4.1 went
1.4.0

Python Polars 1.4.0

Added 4
  • Add nested SQL join support
  • Add support for binary size method to Expr and Series bin namespace
  • Add IO plugins
  • Add SQL interface support for PostgreSQL dollar-quoted string literals
Changed 7
  • Delay selection expansion
  • Optimize strings slices
  • Make .dt.weekday 20x faster
  • Shrink MemSliceInner enum
  • Push down slice with non-zero offset to Parquet
  • Reduce copy in MemSlice
  • Allow for parsing parquet file where the time zone is stored as lowercase utc
Fixed 9
  • Respect strict argument
  • Multi-output column expressions in frame sort method
  • Fix Asof join by schema
  • Set default flags for FFI plugin
  • Fix glob resolution for Hugging Face
  • Several parquet reader/writer regressions
🚀 Performance improvements
  • Delay selection expansion (#18011)
  • Optimize strings slices (#17996)
  • Make .dt.weekday 20x faster (#17992)
  • Shrink MemSliceInner enum (#17991)
  • Push down slice with non-zero offset to Parquet (#17972)
  • Reduce copy in MemSlice (#17983)
✨ Enhancements
  • Add nested SQL join support (#18006)
  • Push down slice with non-zero offset to Parquet (#17972)
  • Add support for binary size method to Expr and Series "bin" namespace (#17924)
  • IO plugins (#17939)
  • Add SQL interface support for PostgreSQL dollar-quoted string literals (#17940)
  • Allow for parsing parquet file where the time zone is stored as lowercase "utc" (#17925)
🐞 Bug fixes
  • Add nested SQL join support (#18006)
  • Respect strict argument (#17990)
  • Multi-output column expressions in frame sort method (#17947)
  • Fix Asof join by schema (#17988)
  • Set default flags for FFI plugin (#17984)
  • Fix glob resolution for Hugging Face (#17958)
  • Several parquet reader/writer regressions (#17941)
  • Incorrect filter on categorical columns from parquet files (#17950)
  • SQL COUNT(DISTINCT x) should not include NULL values (#17930)
  • Default to None in pycapsule interface export (#17922)
📖 Documentation
  • Fix aggregation guide discrepancies (#18003)
  • Ensure last is never ambiguous with max (#17962)
  • Documentation for Arrow PyCapsule interface integration (#17935)
  • Fix Hugging Face link in user guide (#17943)
🛠️ Other improvements
  • Add unit tests for str.contains_any and str.replace_many (#17961)
  • Suggest allow_null as replacement (#17969)
  • Remove apply_generic, use unary_elementwise (#17902)
  • Add general filters in Parquet (#17910)

Thank you to all our contributors for making this release possible! @JamesCE2001, @MarcoGorelli, @alexander-beedie, @coastalwhite, @deanm0000, @deepyaman, @dependabot, @dependabot[bot], @henryharbeck, @kylebarron, @nameexhaustion, @ritchie46 and @wangxiaoying

View originalPermalink
How 1.4.0 went
1.3.0

Python Polars 1.3.0

Added 12
  • Expose binary_elementwise_into_string_amortized for plugin authors
  • Expose allocator to capsule
  • Support authentication with HuggingFace login
  • Support "BY NAME" qualifier for SQL "INTERSECT" and "EXCEPT" set ops
  • Support PyCapsule Interface in DataFrame & Series constructors
  • Implement Arrow PyCapsule Interface for Series/DataFrame export
Changed 6
  • Decompress in CSV / NDJSON scan
  • Ensure unique names in HConcat
  • Write data at table level in write_excel
  • Optimise read_excel when using "calamine" engine with the latest fastexcel
  • Expose 'strict' argument to 'is_in'
  • Release the GIL in collect_schema
Fixed 4
  • Properly write nest-nulled values in Parquet
  • Improve default write_excel int/float format when using a dark "table_style"
  • Fix from_arrow for struct type
  • Fix bool/string usage of "column_totals" parameter in write_excel
🚀 Performance improvements
  • Ensure metadata flags are maintained on vertical parallelization (#17804)
  • Ensure only nodes that are not changed are cached in collapse optimizer (#17791)
  • Use bitflags for OptState (#17788)
  • Remove async directory auto-detection (#17779)
  • Fix accidental quadratic horizontal concat (#17783)
  • Batch parquet integer decoding (#17734)
  • Use mmap-ed memory if possible in Parquet reader (#17725)
  • Use bitflags for function options (#17723)
  • Also set target features and tune cpu for CC (#17716)
  • Introduce MemReader to file buffer in Parquet reader (#17712)
✨ Enhancements
  • Expose binary_elementwise_into_string_amortized for plugin authors, recommend apply_into_string_amortized instead of apply_to_buffer (#17903)
  • Expose allocator to capsule (#17817)
  • Decompress in CSV / NDJSON scan (#17841)
  • Ensure unique names in HConcat (#17884)
  • Support authentication with HuggingFace login (#17881)
  • Enable collection with gpu engine (#17550)
  • Support "BY NAME" qualifier for SQL "INTERSECT" and "EXCEPT" set ops (#17835)
  • Write data at table level in write_excel (#17757)
  • Support PyCapsule Interface in DataFrame & Series constructors (#17693)
  • Implement Arrow PyCapsule Interface for Series/DataFrame export (#17676)
  • Raise informative error instead of panicking when passing invalid directives to to_string for Date dtype (#17670)
  • Implement forward/backward fill for all types (#17861)
  • Implement is_in operation on decimal type (#17832)
  • Optimise read_excel when using "calamine" engine with the latest fastexcel (#17735)
  • Support hf:// in read_(csv|ipc|ndjson) functions (#17785)
  • Allow literals in sort (#17780)
  • Expose 'strict' argument to 'is_in' (#17776)
  • Release the GIL in collect_schema (#17761)
  • Cloud support for NDJSON (#17717)
  • Support API token for scanning hf:// (#17682)
🐞 Bug fixes
  • Scanning '%' from cloud (#17890)
  • Raise suitable error when invalid column passed to get_column_index (#17868)
  • Respect glob=False for cloud reads (#17860)
  • Properly write nest-nulled values in Parquet (#17845)
  • Improve default write_excel int/float format when using a dark "table_style" (#17869)
  • Fix from_arrow for struct type (#17839)
  • Fix bool/string usage of "column_totals" parameter in write_excel (#17846)
  • Infer decimal scales on mixed scale input (#17840)
  • Don't ignore timezones in list of dicts constructor (#14211)
  • Raise on unsupported fill strategy dtype (#17837)
  • Properly write nested NullArray in Parquet (#17807)
  • Check input type on list.to_struct (#17834)
  • Fix right join schema (#17833)
  • Simultaneous usage of named_expr and schema in pl.struct (#17768)
  • Fix projection pusdhown of literals without names (#17778)
  • Don't expand HTTP paths (#17774)
  • Check funtion input len at expansion (#17763)
  • Don't panic in invalid agg_groups (#17762)
  • Raise empty struct (#17736)
  • Fix GC logic in write_ipc (#17752)
  • Panic in pl.concat_list and list.concat on empty inputs (#17742)
  • Fix out nullability for structs coming from arrow (#17738)
  • Percent encode for Hugging Face paths (#17718)
📖 Documentation
  • Updating the join example input for rust for consistency with python example (#17898)
  • Improve filter documentation (#17755)
  • Reword "how" param docstring entry for 'semi' and 'anti' join types for clarity (#17843)
  • Mention read_* functions in Hugging Face section in user guide (#17799)
  • Show return type for Series attributes in API reference (#17759)
  • Add function with multiple arguments example to Expr.map_batches (#17789)
  • Add Hugging Face section to user guide (#17721)
📦 Build system
  • Update Rust toolchain to nightly-2024-07-26 (#17891)
  • Correctly reference released package in optional dependencies (#17691)
🛠️ Other improvements
  • On Python release, trigger docs build after API reference build (#17904)
  • Set uv pip install to verbose (#17901)
  • Fix broken typos command in make pre-commit for py-polars folder (#17897)
  • Remove HybridRLE iter / batch nested parquet decoding (#17889)
  • Add version field for python IR (#17876)
  • Pass through missing rolling and stringfunction information in pyir (#17702)
  • Make better use of typos configuration features (#17800)
  • Better deprecate message for _import_from_c (#17753)
  • Rename Unit to Plain in Parquet reader (#17751)
  • Unpin setuptools (#17726)
  • Update CODEOWNERS (#17707)

Thank you to all our contributors for making this release possible! @MarcoGorelli, @Object905, @SandroCasagrande, @alexander-beedie, @atigbadr, @coastalwhite, @deanm0000, @delsner, @dependabot, @dependabot[bot], @henryharbeck, @implicit-apparatus, @jparag, @knl, @kylebarron, @lukapeschke, @mcrumiller, @nameexhaustion, @orlp, @ritchie46, @ruihe774, @stinodego, @szepeviktor and @wence-

View originalPermalink
How 1.3.0 went
1.2.1

Python Polars 1.2.1

Added 3
  • Expose Arrow C interface directly on Polars
  • Include file path option for NDJSON
  • Add reduce ComputeNode in new streaming engine
Changed 3
  • Specify tune-cpu and add more features for performance optimization
  • Improve garbage collection and push_view for binviews
  • Raise error instead of panic in unsupported serde
Fixed 7
  • Use bytemuck in slice reinterpret for Parquet ArrayChunks
  • Remove non-existing names from __all__
  • Fix return type hint for LazyFrame sink methods
  • Propagate struct outer nullability eagerly
  • Address read_database issue with batched reads from Snowflake
  • Use ETag for HTTP file cache invalidation
  • Fix default name for value_counts methods based on normalize parameter
🚀 Performance improvements
  • Specify tune-cpu & add more features (#17615)
  • Better GC and push_view for binviews (#17627)
✨ Enhancements
  • Raise error instead of panic in unsupported serde (#17679)
  • Expose Arrow C interface directly on Polars (#17696)
  • Include file path option for NDJSON (#17681)
🐞 Bug fixes
  • Use bytemuck in slice reinterpret for Parquet ArrayChunks (#17700)
  • Remove non-existing names from __all__ (#17494)
  • Fix return type hint for LazyFrame sink methods (#17698)
  • Propagate struct outer nullability eagerly (#17697)
  • Address read_database issue with batched reads from Snowflake (#17688)
  • Use ETag for HTTP file cache invalidation (#17684)
📖 Documentation
  • Fixed default name for value_counts methods based on normalize parameter (#17685)
📦 Build system
  • Pin setuptools to fix failing CI (#17695)
🛠️ Other improvements
  • Fix return type hint for LazyFrame sink methods (#17698)
  • Pin setuptools to fix failing CI (#17695)
  • Name tests so they actually run (#17690)
  • Add reduce ComputeNode in new streaming engine (#17389)

Thank you to all our contributors for making this release possible! @5j9, @ByteNybbler, @MarcoGorelli, @alexander-beedie, @coastalwhite, @diegoglozano, @eitsupi, @nameexhaustion, @orlp, @ragyabraham, @ritchie46 and @ruihe774

View originalPermalink
How 1.2.1 went
1.2.0

Python Polars 1.2.0

Added 5
  • Add infer_schema parameter to read_csv / scan_csv
  • Add option to include file path for Parquet, IPC, CSV scans
  • Support describe on decimal
  • Support use of SQLAlchemy Connectable in write_database
  • Hugging Face path expansion
Changed 6
  • Cache path resolving of scan functions
  • Add fastpath for when rounding by single constant durations
  • Improve parallelism in writing hive parquet
  • Support datetime in predicate during hive partition pruning
  • Collect Parquet dictionary binary as view
  • Expose returns_scalar to map_elements
Fixed 9
  • Fix pathological performance issue in window-order-by
  • Support duplicate expression names when calling ufuncs
  • Interpret %y consistently with Chrono in to_date/to_datetime/strptime
  • Fix explode invalid check
  • Expand brackets in async glob expansion
  • Fix row index disappearing after projection pushdown in NDJSON
🚀 Performance improvements
  • Fix pathological perf issue in window-order-by (#17650)
  • Cache path resolving of scan functions (#17616)
  • Add ArrayChunks to optimize codegen of BatchDecoder (#17632)
  • Rechunk before we go into grouped gathers (#17623)
  • Cache schema resolve back to DSL (#17610)
  • Add fastpath for when rounding by single constant durations (#17580)
  • Improve parallelism in writing hive parquet (#17512)
  • Support datetime in predicate during hive partition pruning (#17545)
  • Batch nested embed parquet decoding (#17549)
  • Batch nested Parquet decoding (#17542)
  • Collect Parquet dictionary binary as view (#17475)
✨ Enhancements
  • Hugging Face path expansion (#17665)
  • Add DSL validation for cloud eligible check (#17287)
  • Raise informative error message if non-IntoExpr is passed by name in *Frame.group_by (#17654)
  • Add infer_schema parameter to read_csv / scan_csv (#17617)
  • Change API for writing partitioned Parquet to reduce code duplication (#17586)
  • Cache schema resolve back to DSL (#17610)
  • Expose returns_scalar to map_elements (#17613)
  • Add option to include file path for Parquet, IPC, CSV scans (#17563)
  • Support describe on decimal (#15092)
  • Support datetime in predicate during hive partition pruning (#17545)
  • Raise more informative error message for directories containing files with mixed extensions (#17480)
  • Exclude empty files from directory/glob expansion (#17478)
  • Support use of SQLAlchemy "Connectable" in write_database (#17470)
🐞 Bug fixes
  • Support duplicate expression names when calling ufuncs (#17641)
  • Interpret %y consistently with Chrono in to_date/to_datetime/strptime (#17661)
  • Fix explode invalid check (#17651)
  • Raise for overlapping index/column names in pandas dataframes post string coercion (#17628)
  • Expand brackets in async glob expansion (#17630)
  • Fix row index disappearing after projection pushdown in NDJSON (#17631)
  • Fix struct -> enum is_in (#17622)
  • Don't needlessly unwrap in pivot_schema (#17611)
  • Reject literal input in sort_by_exprs() (#17606)
  • Don't enforce row order in join test results where not guaranteed (#17596)
  • Bitmap collect into safety (#17588)
  • Make schema picklable (#17524)
  • Handle current position of file objects (#17543)
  • Set O_CLOEXEC on duplicated file descriptor (#17537)
  • Method dt.truncate was sometimes returning incorrect results for pre-1970 datetimes (#17582)
  • Defer path expansion until collect in file scan methods (#17532)
  • Fix retries parameter in scan functions not taking effect when it was set to 0 (#17564)
  • Don't unwrap send attempt to oneshot channel (#17566)
  • Fix scanning from HTTP cloud paths (#17571)
  • Properly implement struct (#17522)
  • Add right to lazyframe join docstring (#17529)
  • Fix predicate pushdown for .list.(get|gather) (#17511)
  • Make sure scan_ipc does not go through fsspec (#17495)
  • Turn panic into error when serializing Object types (#17353)
  • Fix struct expansion and raise on exclude (#17489)
  • Normalize path in sink_csv (#17476)
📖 Documentation
  • Update plot docs to refer to docstrings (#17504)
  • Rename str.lengths to str.len_bytes in description text (#11577) (#17626)
  • Create example for polars.Expr.bin.decode (#17508)
  • Add right join in the user guide (#17608)
  • Adjust rendering of links in read_database_uri docstring (#17536)
  • Update SQL examples in README (#17568)
  • Fixup "deprecated" directive for DataFrame.melt and LazyFrame.melt (#17530)
  • Add write_parquet_partitioned (#17488)
  • Add example for writing hive partitioned parquet to user guide (#17483)
  • Fix typo in Getting Started section of user guide (#17465)
🛠️ Other improvements
  • Add DSL validation for cloud eligible check (#17287)
  • Add ArrayChunks to optimize codegen of BatchDecoder (#17632)
  • Move path logic to from utils to path_utils in polars-io (#17635)
  • Fix struct gather (#17621)
  • Back to StructChunked name (#17609)
  • Remove unused with_column method of PyLazyFrame (#17607)
  • Re-enable struct related tests (#17597)
  • Completely redo structure of Parquet decoder (#17589)
  • Fix struct outer validity;fmt;is_in;cast;cmp (#17590)
  • Add/fix version-gating in some SQLAlchemy and Pandas tests (#17538)
  • Add style accessor to DataFrame (#17502)
  • Remove unused is_supported_cloud util (#17493)

Thank you to all our contributors for making this release possible! @Julian-J-S, @MarcoGorelli, @alexander-beedie, @anergictcell, @arnabanimesh, @brandon-b-miller, @cmdlineluser, @coastalwhite, @deanm0000, @eitsupi, @flisky, @henryharbeck, @itamarst, @jonaylor89, @moritzwilksch, @nameexhaustion, @orlp, @phi-friday, @r-brink, @rcorty, @ritchie46, @ruihe774, @stinodego, @tylerriccio33 and @wence-

View originalPermalink
How 1.2.0 went
1.1.0

Python Polars 1.1.0

Added 5
  • Add future arg to Series.to_arrow
  • Add future versioning
  • Support writing hive partitioned parquet
  • Add right join support
  • Support hive partitioning in scan_ipc
Changed 7
  • Keep more parallelism when CSE plan cache hits
  • Batch parquet primitive decoding
  • Respect allow_threading in some more operators
  • Parallelize parquet metadata deserialization
  • Use underlying fileno for Python files when possible
  • Apply slice pushdown immediately to in-memory frames
  • Improve error message when passing string key to Series.__getitem__
Fixed 8
  • Handle DB cursor descriptions that contain more fields than the DBAPI2 standard
  • Fix decimal dyn float supertype
  • Verify the integrity of pandas column names before implied string conversion
  • Don't rechunk on phys_repr
  • Harden alchemy session for old sqlalchemy versions
  • Fix swapping rename schema
  • Make boolean reads consistent across all read_excel engines
  • Raise on oob decimal precision
🚀 Performance improvements
  • Keep more parallelism when CSE plan cache hits (#17463)
  • Batch parquet primitive decoding (#17462)
  • Respect allow_threading in some more operators (#17450)
  • Parallelize parquet metadata deserialization (#17399)
  • Use underlying fileno for Python files when possible (#17315)
  • Add future arg to Series.to_arrow (#17371)
✨ Enhancements
  • Add "future" versioning (#17421)
  • Apply slice pushdown immediately to in-memory frames (#17459)
  • Support writing hive partitioned parquet (#17324)
  • Add right join support (#17441)
  • Support hive partitioning in scan_ipc (#17434)
  • Improve error message when passing string key to Series.__getitem__ (#17408)
🐞 Bug fixes
  • Handle DB cursor descriptions that contain more fields than the DBAPI2 standard (#17468)
  • Fix decimal dyn float supertype (#17464)
  • Verify the integrity of pandas column names before implied string conversion (#17433)
  • Don't rechunk on phys_repr (#17461)
  • Harden alchemy session for old sqlalchemy versions (#17366)
  • Fix swapping rename schema (#17458)
  • Make boolean reads consistent across all read_excel engines (#17448)
  • Raise on oob decimal precision (#17445)
  • Fix handling of TextIOWrapper in write_csv (#17328)
  • Support sa session (#17435)
  • Fix from_pandas for string columns with missing values (#17397)
  • Fix a global variable table-discovery edge case for the SQL interface (#17400)
  • Don't allow json inference method to be chunked/streaming (#17396)
  • Set literal nesting to 0 (#17392)
  • Fix scanning cloud paths with spaces (#17379)
  • Fix slice length no longer allowing None (#17372)
  • Fix typo in SchemaError exception message (#17350)
  • Raise proper error for mismatching parquet schema instead of panicking (#17321)
📖 Documentation
  • Add examples for scanning hive datasets to user guide (#17431)
  • Update partition_by docstring to match new behavior (#17394)
  • Update GroupBy.__iter__ docstring to match new behavior (#17383)
📦 Build system
  • Add support for NumPy 2.0 (#17384)
🛠️ Other improvements
  • Add automated check for PR title formatting (#17412)
  • Remove transmute for object store path (#17395)
  • Fix Python version resolver in release drafter (#17390)
  • Avoid use of np.trapz in tests to prepare for NumPy 2.0 (#17387)
  • Avoid writing to disk when running sink_csv test (#17386)

Thank you to all our contributors for making this release possible! @alexander-beedie, @brunobbaraujo, @cmdlineluser, @coastalwhite, @dependabot, @dependabot[bot], @nameexhaustion, @orlp, @phi-friday, @ritchie46, @ruihe774, @sherlockbeard, @stinodego, @tylerriccio33 and @wence-

View originalPermalink
How 1.1.0 went
View all

Discussion