9月12日、ソフトウェアエンジニアのEddieが「Pandas Should Go Extinct」と題した記事を公開した。PythonのDataFrameライブラリとして長年データ分析の標準とされてきたPandasを捨て、PolarsやDuckDBに移行すべきだという主張だ。ベンチマークでは最大53倍の速度差が示されており、その根拠は単なる性能比較にとどまらない。
「Pandasの崖」と分散システムの間にある盲点
データ分析ツールの典型的な移行経路はこうだ。ExcelからPandasへ、そして扱うデータが数十GBを超えたあたりでPandasが限界を迎え、SparkやDatabricks、Snowflakeといった分散処理システムへ移行する。しかしこの経路には見落とされがちな盲点がある。Pandasが苦しくなるスケールと、分散システムが本当に必要になるスケールの間には大きなギャップがあるのだ。
そのギャップはおよそ100GB付近に存在し、現代のシングルマシン向けツールで十分に埋められる──というのがEddieの中心的な主張だ。

あなたのデータは「Big Data」ではない
この主張を裏付けるのが、2024年にAmazonが公開した論文「Why TPC is not enough: An analysis of the Amazon Redshift fleet」だ。Amazon RedshiftはAmazonが提供するクラウド型の分散分析データベースで、多くの企業が本番データ基盤として採用している。同論文のフリート統計に対し、いくつかの仮定(テーブルの平均行サイズ1KB、クラスターは10台構成で各マシンがS3から8GB/sでデータを読み込む)を置いて分析すると、次の結論が得られる。
- Redshiftフリートのテーブルのうち94.68%は100GB未満のデータしか持たない
- クエリの86.9%は80GB以下のデータに対して実行されている


実際に分散データウェアハウスを使っている企業の大半でも、データの規模は「Medium Data」の域に収まっている。それならば、分散システムの運用コストや複雑さを抱え込む前に、シングルマシンで動く高速ツールを使えばよい。
代替ツール:PolarsとDuckDB
Eddieが提案するのはPolarsとDuckDBの2つだ。
- **Polars**:Rustで書かれたDataFrameライブラリ。APIはPandasに近く学習コストが低い。遅延評価(Lazy Evaluation)により実際の計算をできる限り後回しにしてクエリ全体を最適化した上で実行するため無駄な処理が減り、マルチスレッドによる並列処理と組み合わさって大きなパフォーマンス向上をもたらす
- **DuckDB**:インプロセスで動作する分析用データベース。「分析用SQLite」とも称され、SQL構文でDataFrameやCSVを直接操作できる。サーバーが不要でPythonから1行で使い始められる
2つの違いを比較するために、Eddieは1 Billion Row Challengeを用いた。10億行のCSVから気象観測所ごとの最小・平均・最大気温を集計するという課題で、メモリ効率と処理速度の両方を測る定番ベンチマークだ。
コード比較
Pandasはデータ全体を一括読み込みし、シングルスレッドで逐次処理する:
def do_1brc_pandas(file_path: str):
df = (
pd.read_csv(file_path, sep=";", names=["station", "measurement"])
.groupby("station")
.agg({"measurement": ["min", "mean", "max"]})
.round(2)
)
Polarsはscan_csvで遅延評価し、.collect(new_streaming=True)でチャンク単位の並列処理を実行する(new_streamingは執筆時点で実験的API):
def do_1brc_polars(file_path: str):
df = (
pl.scan_csv(
file_path,
separator=";",
new_columns=["station", "measurement"],
has_header=False,
)
.group_by("station")
.agg(
pl.col("measurement").min().round(2).alias("min"),
pl.col("measurement").mean().round(2).alias("mean"),
pl.col("measurement").max().round(2).alias("max"),
)
.collect(new_streaming=True)
)
DuckDBはPythonオブジェクトに直接SQLを発行でき、コードが簡潔だ:
def do_1brc_duckdb(file_path: str):
df = duckdb.read_csv(file_path, names=["station", "measurements"])
src = duckdb.sql("""
create table src as
select
station,
min(measurements) min,
max(measurements) max,
cast(avg(measurements) as decimal(8, 1)) avg
from df
group by station
"""
)
ベンチマーク結果:数字が全てを語る
テスト環境はAWS m7a.8xlarge(32コア、128GB RAM)。ハイスペックなクラウド環境ではあるが、後述するラップトップ環境でも傾向は変わらない。
| ライブラリ | 中央値(実行時間) | 最大CPU使用率 | 最大メモリ(USS) | 最大スワップ |
|---|---|---|---|---|
| Pandas | 4分28秒 | 113.0% | 38.12 GB | 0 MB |
| Polars | 5.04秒 | 3202.60% | 18.02 GB | 0 MB |
| DuckDB | 5.19秒 | 3174.64% | 1.93 GB | 0 MB |
PolarsとDuckDBはPandasに対してそれぞれ約53倍・約52倍高速。メモリ消費はPolarsが約2分の1、DuckDBは約19分の1に抑えられている。なお、同チャレンジの手書きJava実装による最速記録が約1.5秒であることを考えると、この2ツールはそれに肉薄する水準だ。
ローカル開発環境(Framework 13、Intel i5-1135G7、8コア、16GB RAM)でも傾向は変わらない:
| ライブラリ | 中央値(実行時間) | 最大スワップ |
|---|---|---|
| Pandas | 12分15秒 | 21.02 GB |
| Polars | 39秒 | 35.85 MB |
| DuckDB | 47秒 | 0 MB |
Pandasは21GBものスワップを消費しながら12分以上かかる一方、DuckDBはスワップゼロで47秒で完了している。メモリが限られたラップトップ環境ほど差が顕著に出る点は、日常の分析作業にとって無視できない。
移行コストはほぼゼロ:Apache Arrowという接着剤
既存のPandasコードを全て書き直す必要はない。Apache Arrowがその橋渡しをする。ArrowはPandasの開発者であるWes McKinneyが設計に深く関与した列指向データのインメモリ表現形式で、PolarsとDuckDBの両方がネイティブ対応している。
Pandas 2.0以降ではArrowバックエンドをサポートしており、dtype_backend="pyarrow"を指定するだけでPandas・Polars・DuckDB間のDataFrame受け渡しがメモリコピーなしに行える。ホットパスだけPolarsに切り出すといった段階的な移行も現実的だ。
「Big Dataツールは過剰売込みされている」
Eddieの主張の核心は技術的な性能差だけにとどまらない。「SparkやSnowflakeはBig Dataツールとして巧みにマーケティングされているが、多くの現場では過剰なコストと複雑性を持ち込むだけだ」という指摘は、前述のRedshiftフリート統計によって実証的に裏付けられている。
データエンジニアリングのコミュニティでは以前から「Modern Data Stackは複雑になりすぎた」という声が上がっており、本記事はその議論に実データを持ち込んだ形だ。ツール選定の基準は「将来的にBig Dataになるかもしれない」という恐れではなく、「今のデータ規模で最も生産性が高いか」であるべきだというEddieのメッセージは、現場のデータエンジニアや分析者にとって再考を促す。
もちろん、PandasにはNumPyや機械学習ライブラリとの豊富なエコシステムという強みがあり、全てのユースケースで置き換えられるわけではない。しかし「とりあえずPandas」という慣習を一度疑ってみる価値は十分にある。
詳細はPandas Should Go Extinctを参照していただきたい。