データ処理をPythonで書いていると、ある日突然「Polarsって知ってる?pandasより速いらしいよ」って言われる瞬間がくる。自分はその瞬間が数ヶ月前にきて、ちょっと調べてみたらそのまま沼った。
この記事は「Polarsって何?pandasと何が違うの?」というところから、基本的な書き方の比較、どっちを使うべきかの判断まで、できるだけ平易にまとめたものです。
この記事でわかること
- Polarsとpandasそれぞれがどんなライブラリなのか
- データ読み込み・フィルタ・集計の書き方の違い
- Polarsの遅延評価(LazyFrame)がなぜ速いのか
- どちらのライブラリを使うべき場面
- pandasからの移行で注意すべきポイント
Polarsとは何か
PolarsはRust製の高速データフレームライブラリです。PythonからはAPIを通じて使えるので、普段Pythonを書いている分には「速いpandasっぽいもの」として触れられます。
pandasがPythonとNumPyの上に構築されているのに対し、PolarsはRustで実装されており、内部でApache Arrowを採用しています。これが速さの根っこにある話で、以下の3つが主なポイントです。
- 並列処理(マルチスレッド):CPUの複数コアを使って処理を並列で走らせる
- 列指向メモリ構造:データを列ごとにまとめて持つことで、集計・フィルタが効率的
- 遅延評価(Lazy evaluation):処理をためてから最適化して実行する
実際のベンチマークでは、pandasと比較して大きく高速化したり、メモリ使用量が減ったりする結果が報告されているようです。もちろんデータの種類や処理内容によって変わりますが、大規模データになるほどPolarsが有利になる傾向はあります。
余談ですが、Polarsという名前は「Polar bear(ホッキョクグマ)」から来てると言われています。ロゴもそのまんまクマです。かわいい。
インストール方法
pipでも普通に入ります。最近はアクティブに更新されています。
# pip の場合
pip install polars
# uv の場合(最近はこっちのほうが速くて好き)
uv add polars
Python 3.10以上が必要です。古い環境を使ってる場合はそこだけ注意です。
pandas vs Polars 基本構文の比較
書き方がけっこう違うので、慣れるまでは「あれ、これどう書くんだっけ」が連発します。主要な操作をpandasと並べて比較していきます。
データ読み込み
import pandas as pd
import polars as pl
# pandas
df_pd = pd.read_csv("data.csv")
# Polars(即時実行)
df_pl = pl.read_csv("data.csv")
# Polars(遅延実行 ※大きいファイルはこっちが有利)
lf = pl.scan_csv("data.csv")
scan_csvはファイルを即座にメモリに読み込まず、後続の処理と一緒に最適化してから実行してくれます。さらにメモリに収まらない規模のデータでも、ストリーミング実行などを使うことでメモリ使用量を抑えられる場合があります(環境や処理内容に依存します)。
列の選択とフィルタ
# pandas
result_pd = df_pd[["name", "age"]]
filtered_pd = df_pd[df_pd["age"] > 20]
# Polars
result_pl = df_pl.select(["name", "age"])
filtered_pl = df_pl.filter(pl.col("age") > 20)
Polarsでは pl.col("列名") のように「列」を指定して操作するのが基本です。最初は冗長に感じるんですが、複雑な条件を書き始めると逆にこっちのほうが読みやすい気はします。
新しい列の追加
# pandas
df_pd["age_x2"] = df_pd["age"] * 2
# Polars(列追加/変更はwith_columnsが基本)
df_pl = df_pl.with_columns(
(pl.col("age") * 2).alias("age_x2")
)
Polarsでは、pandasみたいに df["col"] = ... の形で列を追加・置換するのはできません(TypeErrorになります)。基本は with_columns() を使って新しいDataFrameを返す形になります。これ最初めちゃくちゃ戸惑いました。
グループ集計
# pandas
agg_pd = df_pd.groupby("category").agg({"value": ["sum", "mean"]})
# Polars
agg_pl = df_pl.group_by("category").agg([
pl.col("value").sum().alias("value_sum"),
pl.col("value").mean().alias("value_mean")
])
ちなみにPolarsは groupby ではなく group_by(アンダースコアあり)です。最初何度かtypoしました。こういう細かい差が地味にハマりポイントです。
Polarsの目玉機能:遅延評価(LazyFrame)
Polarsは遅延実行(lazy execution)モデルを採用しており、データ変換の一連の処理を、即座に実行することなく構築できます。Polarsはパイプライン全体を解析し、最適な実行計画を生成することで、不要な操作を排除し、データ走査回数を減らし、実行順序を最適化できます。
result = (
pl.scan_csv("large_data.csv") # メモリに全量読まない
.filter(pl.col("region") == "East")
.group_by("date")
.agg(pl.col("sales").sum())
.sort("date")
.collect() # ここで初めて実行される
)
Polarsでは、selectやfilterを積んでも実際の処理はcollect()を呼ぶまで実行されません。つまり、不要な列・行を事前に除外できるため、I/Oやメモリ使用を最小限に抑えられます。
実務での事例では大規模なデータをメモリ効率よく処理し、従来のpandas実装と比較して顕著な高速化と省メモリ化を実現したという話もあるみたいです。処理の最適化計画は lf.explain() で確認できます。個人的にはこれが地味に好きで、「Polarsがどう考えてるか」が見えて面白い。
pandasとどっちを使うべきか
これ、結論から言うと「両方知っておいて、状況で使い分ける」が現実的な答えかなと思います。
pandasが向いているケース
- データ量が小〜中規模(数万〜数十万行くらいまで)
- 既存のエコシステム(scikit-learn, matplotlib等)との連携が多い
- チームにpandasユーザーが多く、学習コストを抑えたい
- 試行錯誤しながらインタラクティブに分析したい
Polarsが向いているケース
- 100万行以上の大規模データを扱う
- バッチ処理やETLパイプラインなど、処理速度が重要なとき
- メモリの制約が厳しい環境
- Parquetファイルを大量に扱う処理
pandasとの相互変換は df.to_pandas() と pl.from_pandas(df) でできるので、「部分的にPolarsを使って速い処理だけ任せる」という混在パターンも普通に使えます。
Polarsはまだ新しいライブラリであり、ドキュメンテーションやサポートの面でpandasには及びません。また、Rustで実装されているため、Pythonの文法とは異なる部分もあり、学習コストはやや高めと言えます。pandas慣れしてる人ほど最初は違和感があるはずです。でも慣れてくると「pandasのapplyでゴリ押しするよりPolarsのexpressionsのほうが気持ちよく書ける」という感覚になってきます(自分はなりつつあります)。
pandasからPolarsへの移行で注意すること
いくつか自分がハマった・詰まったポイントを雑にまとめておきます。
NaNではなくnull:Polarsは欠損値をnullで扱います。pandasのisna()ではなくis_null()を使います- インデックスがない:pandasにある行インデックスの概念がPolarsにはありません。
df.loc[]やdf.iloc[]は使えない - applyが基本ない:pandasの apply のようにラムダ式を渡して行ごとにループする操作とは異なり、Polarsはほぼあらゆる操作をexpressionsとして表現できます。行ごとのUDFも一応できますが、基本はexpressionsに寄せて書くほうがPolarsっぽいです
groupby→group_by:さっきも書きましたが何度でも書きます。アンダースコア
正直まだ自分も完全に乗り換えられてはいなくて、Jupyter上でサクッと試したいときはpandasを使って、処理が重くなってきたらPolarsに書き直す、という感じで使っています。もっとスマートなやり方がありそうな気がするけど、まあそれはおいおい。
Polarsのドキュメントは英語ですが読みやすい方だと思います。公式のユーザーガイドにはpandasとの対比で書かれているセクションもあるので、「pandasでこれやるには?」と調べながら移行するのが地味に効率よかったです。
※この記事にはプロモーションが含まれます
ちなみに、お名前.com レンタルサーバー(WordPressに特化した高速レンタルサーバー。月額990円〜、独自ドメイン実質0円)も気になっています。お名前.com レンタルサーバー![]()
まとめ
Polarsはpandasに比べて速度とメモリ効率で優れていますが、大規模データ処理に限った話ではありません。ただし学習コストがあり、pandasとの構文の違いもあります。
- 小〜中規模のデータ分析ならpandasで十分
- 大規模データやバッチ処理はPolarsを検討する価値あり
- 両者は相互変換できるので、使い分けや混在も実践的
- 移行時はnull/is_null、group_byなどの細かい違いに注意
Polars還暦とか言ってる人もいますし、Rustベースのデータ処理ツールの流れは確実に来てる気がします。pandas一本でいくのもありですが、「こういう選肢がある」ぐらいの感覚で頭の片隅に置いておくと、いざ遅い処理に困ったときに思い出せるかもしれません。
