HN 日本語サマリー

← 一覧へ戻る
プログラミング

Polars 2.0 のリリース候補版について

Pre-Release of Polars 2.0 (pola.rs)

366 pointsby komape121 コメント

要約

データフレームライブラリPolarsのバージョン2.0のリリース候補版が公開されました。このメジャーバージョンアップでは、大きな機能追加ではなく、過去の設計上の制約を取り除き、デフォルト設定をより合理的で多くのユーザーに有益なものに変更することに重点が置かれています。最も重要な変更点は、LazyFrameクエリがデフォルトでストリーミングエンジンを使用するようになり、メモリ使用量とパフォーマンスが大幅に向上する見込みです。

全文翻訳

ブログに戻る Polars 2.0 のリリース候補版 By Ritchie Vink on Wed, 2 Sept 2026 本日、Polars 2.0 の最初のリリース候補版をリリースします。正式な 2.0 リリースは数週間以内に登場します。Polars 2.0 では、大きな機能リリースを目指していません。実際、皆様にとっては退屈な体験になることを願っています。メジャーバージョンを更新する理由は、過去に行われた、現在私たちを妨げている設計上の決定を排除し、より多くのユーザーに利益をもたらす、より合理的な設定にデフォルトを変更したいからです。最大のデフォルト変更は、すべての LazyFrame クエリがストリーミングエンジンで実行されるようになることです。そのため、カジュアルな Polars ユーザーは、メモリ使用量とパフォーマンスにおいて大幅な改善を期待できます。全体として、ストリーミングエンジンは 5 倍高速になると予想しています。ユーザーが 2.0 に移行するのを支援するために、完全な移行ガイドを公開しました。この記事では、いくつかのハイライトを取り上げます。 ストリーミングエンジンをデフォルトに これは 2.0 における最も影響の大きい変更です。LazyFrame に対して collect を呼び出すと、デフォルトでストリーミングエンジンが使用されるようになり、ほとんどのクエリでユーザーのメモリ使用量とパフォーマンスが劇的に向上します。この変更がメジャーバージョンアップを必要とした理由は、ストリーミングエンジンがデフォルトでは特定の操作(join, group_by, unpivot など)で行順序を保証しないためです。これらの操作で観測可能な行順序が必要な場合は、maintain_order=True を設定することでオプトインできます。デフォルトで古い「インメモリ」エンジンを使用し続けたいユーザーは、engine affinity を設定することでそれが可能です。 lf = pl.LazyFrame({"k": [2, 1, 0], "v": ["a", "b", "c"]}) other = pl.LazyFrame({"k": [0, 1, 2], "r": ["x", "y", "z"]}) # 2.0: engine="auto" はストリーミングエンジンに解決されます。 # join, group_by, unpivot などでは行順序は保証されなくなります。 # ( lf .join(other, on="k", how="left") .collect() ) # ┌─────┬─────┬─────┐ # │ k ┆ v ┆ r │ <- 元の lf の行順序と一致しない場合があります # └─────┴─────┴─────┘ # このクエリで観測可能な順序をオプトインする: # ( lf .join(other, on="k", how="left", maintain_order="left") .collect() ) # または、プロセス全体で古いインメモリエンジンをデフォルトとして維持する: # pl.Config.set_engine_affinity("in-memory") # ...またはクエリごと: # ( lf .join(other, on="k", how="left") .collect(engine="in-memory") ) より厳格な Polars Polars は厳格であり、早期に失敗することを目指しています。エラーは、パイプラインの 20 分後に発生するのではなく、理想的には事前に発生すべきです。データ不一致に対する暗黙の動作は、それらの不一致がバグを隠す可能性があるため、デフォルトではなくオプトインであるべきです。この厳格さは、AI 駆動開発の台頭により、さらに価値が高まっています。エージェントは、collect_schema() を呼び出すことでクエリの構造を早期に検証でき、データの実体化なしに型を解決し、スキーマレベルの不一致を検出できます。これにより、エージェントは迅速なフィードバックを得られ、より速くイテレーションできるようになります。すべてのエラーがクエリプランのコンパイル中に捕捉できるわけではなく、一部はデータに依存します。これらの場合、Polars は不整合がサイレントに異なる結果を生成するのではなく、検出されることを保証するために、より厳格な動作をデフォルトとします。以下に、Polars がより厳格になった例をいくつか示します。 is_in の非可逆的な型変換 異なるデータ型に対して is_in 式を実行すると、Polars は、その変換が非可逆的であっても、共通のスーパータイプに両方の型をキャストしていました。以下は、サイレントなデータ型不一致によって問題が発生する可能性のあるユーザー ID の例です。 # "フラグ付けされた" アカウント ID のリストとユーザー ID が一致するかどうかを確認する # (flagged_ids は JSON エクスポートからロードされ、大きな ID は float になりました) flagged_ids = pl.Series([9007199254740992.0]) user_id = pl.Series([9007199254740993]) # Int64 -> 1 違いの別の ID user_id.is_in(flagged_ids) 2.0 より前では、user_id は flagged_ids に一致するように Float64 にキャストされていました。しかし、9007199254740993 は、float64 が正確に表現できる最大の整数である 2^53 (9007199254740992) を超えているため、サイレントに 9007199254740992.0 に丸められ、偽陽性となりました。2.0 では、これは InvalidOperationError: 'is_in' cannot check for Int64 values in List(Float64) data. となり、ユーザーは非可逆的な型変換を処理するために明示的にキャストする必要があります。 厳格な連結 水平連結は、サイレントに null で埋めるのではなく、長さチェックを行うようになります。 # 日ごとのトランザクション数を日ごとの不正フラグ数と結合する transactions = pl.DataFrame({"day": [1, 2, 3, 4, 5], "count": [120, 98, 143, 87, 156]}) # 日 5 のアップストリームジョブがサイレントに失敗した fraud_flags = pl.DataFrame({"flagged": [2, 0, 5, 1]}) # 行は 4 つのみ pl.concat([transactions, fraud_flags], how="horizontal") # shape: (5, 2) # ┌─────┬───────┬─────────┐ # │ day ┆ count ┆ flagged │ # │ 1 ┆ 120 ┆ 2 │ # │ 2 ┆ 98 ┆ 0 │ # │ 3 ┆ 143 ┆ 5 │ # │ 4 ┆ 87 ┆ 1 │ # │ 5 ┆ 156 ┆ null │ <- 日 5 にはフラグカウントがサイレントにありません # └─────┴───────┴─────────┘ 2.0 では、ShapeError: cannot concat dataframes with different heights in 'strict' mode というエラーが発生します。パディングが望ましい場合は、how="horizontal_extend" を使用して明示的にオプトインする必要があります。これにより、読者にとって意図が明確になります。 専用メソッド/コンストラクタを優先したキャストの削除 もう一つ言及する価値があるのは、曖昧なキャストや、専用の解析式を通じて適用されるべきキャストの多くが削除されたことです。これにより、データを解析する明白な方法が一つになりました。 Enum/Categorical <> 整数 pl.Series([None, 1, 0, 2], dtype=pl.UInt32).cast(pl.Enum(["a", "b", "c"])) # ComputeError: casting from u32 to enum is not supported. Use instead: .cat.to(dtype) for int → categorical, .cat.physical() for categorical → int. 文字列から時間データ型への解析 pl.Series(["2022-08-30"]).cast(pl.Date) # InvalidOperationError: casting from string to date is not supported. Use instead: .str.to_date() / .str.to_datetime(). これらにより、解析フォーマットを適用でき、データの解析方法に対するより多くの制御が可能になります。これらはほんの一例ですが、さらに多くの厳格さの改善が実施されました。すべては移行ガイドで確認できます。 情報提供のエラーを発生させる ユーザーまたはエージェントが、サポートされなくなった古いパラメータを使用したとしても、処理を続行できるように、多大な努力を払いました。このために、2 つの新しい型付き例外 polars.exceptions.AttributeRemovedError および polars.exceptions.ArgumentRemovedError を追加しました。これらは、それぞれ削除された属性とメソッド、および削除されたパラメータを処理します。エラーメッセージは、新しい API を指し示すはずです。以下に 2 つの例を示します。 >>> lf.melt(id_vars="a", value_vars="b") polars.exceptions.AttributeRemovedError: `melt` was removed in version 2.0; use `LazyFrame.unpivot` instead, with `index` instead of `id_vars` and `on` instead of `value_vars` >>> df.join(df, on="a", join_nulls=True) polars.exceptions.ArgumentRemovedError: the argument 'join_nulls' for 'DataFrame.join' was deprecated in version 1.24 and has been removed in 2.0.0. It was renamed to 'nulls_equal' in version 2.0. 削除された機能のほとんどは長らく非推奨となっており、最新の状態を維持していれば、パイプラインに影響を与えなかったはずです。依存していた機能があると思われる場合は、私たちに連絡してください。 最後に Polars 2.0 は、より良いデフォルト(最も重要なのはストリーミングエンジン)と、より良い API に関するものです。このリリースがむしろ退屈であることを願っています。新しい機能は、準備ができ次第リリースするため、メジャーバージョンアップの区切りにはしていません。誤解しないでください、Polars 2.x は 1.x よりもはるかに良くなるでしょう。まだ公に話していない多くのことが進行中です。ストリーミングエンジンの適切なアウトオブコアサポート、新しい IO プラグイン設計、おそらく最速の S3 リーダー、SQL カバレッジの大幅な改善、コストベースプランナー、結合順序変更、および mmap の削除により、パイプラインはエンドツーエンドで完全に非同期になります。pip install polars==2.0rc1 をインストールしてリリース候補版を試してみてください。ぜひ触ってみて、ここでフィードバックをお願いします: https://github.com/pola-rs/polars/issues または Discord でご連絡ください: https://discord.gg/4UfP5cfBE7。