データ分析や処理の速度がボトルネックになっていませんか?Polarsは、Pythonで高速かつ効率的にデータを操作するための次世代データフレームライブラリです。その圧倒的な性能は、特に大規模なデータセットで威力を発揮します。本記事では、Polarsの基本的な使い方から、高度な遅延(Lazy)モードまでを解説します。
Polarsとは?
Polarsは、Rustで構築されたPythonのデータ操作ライブラリです。その設計思想はシンプル:「より高速で、効率的なデータ処理を誰でも使えるようにすること」。Pandasに似た操作感で、より強力な性能を発揮します。
インストール
まずはインストールから始めましょう。
pip install polars
インストールが完了したら、以下のコードでPolarsをインポートします。
import polars as pl
Polarsの基本操作
Polarsを使えば、データフレームの作成やフィルタリング、グループ化が簡単に行えます。以下に、いくつかの基本操作を紹介します。
データフレームの作成
辞書から簡単にデータフレームを作成できます。
data = {
"名前": ["太郎", "花子", "次郎"],
"年齢": [25, 30, 22],
"点数": [88, 92, 85]
}
df = pl.DataFrame(data)
print(df)
shape: (3, 3)
┌──────┬──────┬──────┐
│ 名前 ┆ 年齢 ┆ 点数 │
│ --- ┆ --- ┆ --- │
│ str ┆ i64 ┆ i64 │
╞══════╪══════╪══════╡
│ 太郎 ┆ 25 ┆ 88 │
│ 花子 ┆ 30 ┆ 92 │
│ 次郎 ┆ 22 ┆ 85 │
└──────┴──────┴──────┘
CSVファイルの読み込み
既存のCSVファイルも簡単に読み込めます。
df = pl.read_csv("sample.csv")
CSVファイルの書き込み
データをCSVファイルとして保存することもできます。
df.write_csv("data.csv")
データ操作の基本
カラムの選択
特定のカラムを選択するには、カラム名を指定します。
print(df["名前"])
shape: (3,)
Series: '名前' [str]
[
"太郎"
"花子"
"次郎"
]
フィルタリング
データフレームを条件でフィルタリングできます。
filtered_df = df.filter(pl.col("年齢") >= 25)
print(filtered_df)
shape: (2, 3)
┌──────┬──────┬──────┐
│ 名前 ┆ 年齢 ┆ 点数 │
│ --- ┆ --- ┆ --- │
│ str ┆ i64 ┆ i64 │
╞══════╪══════╪══════╡
│ 太郎 ┆ 25 ┆ 88 │
│ 花子 ┆ 30 ┆ 92 │
└──────┴──────┴──────┘
新しいカラムの追加
既存のデータに基づいて新しいカラムを追加するのも簡単です。
df = df.with_columns((pl.col("点数") + 10).alias("点数+10"))
print(df)
shape: (3, 4)
┌──────┬──────┬──────┬─────────┐
│ 名前 ┆ 年齢 ┆ 点数 ┆ 点数+10 │
│ --- ┆ --- ┆ --- ┆ --- │
│ str ┆ i64 ┆ i64 ┆ i64 │
╞══════╪══════╪══════╪═════════╡
│ 太郎 ┆ 25 ┆ 88 ┆ 98 │
│ 花子 ┆ 30 ┆ 92 ┆ 102 │
│ 次郎 ┆ 22 ┆ 85 ┆ 95 │
└──────┴──────┴──────┴─────────┘
グループ化と集計
Polarsは、高速で直感的なグループ化操作を提供します。
grouped_df = df.group_by("名前").agg(pl.col("点数").mean().alias("平均点"))
print(grouped_df)
shape: (3, 2)
┌──────┬────────┐
│ 名前 ┆ 平均点 │
│ --- ┆ --- │
│ str ┆ f64 │
╞══════╪════════╡
│ 太郎 ┆ 88.0 │
│ 次郎 ┆ 85.0 │
│ 花子 ┆ 92.0 │
└──────┴────────┘
条件分岐操作: select と when, then, otherwise の活用
Polarsでは、条件に基づいてカラムの値を操作するために、select
, when
, then
, otherwise
を使用します。これにより、データに対する柔軟な条件付きの変換が可能です。
基本構文
when
: 条件を指定します。then
: 条件が満たされた場合に返す値を指定します。otherwise
: 条件が満たされなかった場合に返す値を指定します。
df = pl.DataFrame({
"名前": ["太郎", "花子", "次郎"],
"点数": [88, 92, 85]
})
# 条件付きカラムを追加(修正版)
df = df.with_columns(
pl.when(pl.col("点数") >= 90)
.then(pl.lit("優秀")) # pl.lit() でラップ
.otherwise(pl.lit("普通")) # pl.lit() でラップ
.alias("評価")
)
print(df)
shape: (3, 3)
┌──────┬──────┬──────┐
│ 名前 ┆ 点数 ┆ 評価 │
│ --- ┆ --- ┆ --- │
│ str ┆ i64 ┆ str │
╞══════╪══════╪══════╡
│ 太郎 ┆ 88 ┆ 普通 │
│ 花子 ┆ 92 ┆ 優秀 │
│ 次郎 ┆ 85 ┆ 普通 │
└──────┴──────┴──────┘
Lazyモードで高速処理を極める
Polarsの最大の特徴の一つがLazyモードです。このモードを活用することで、大規模なデータセットや複雑なクエリを効率的に処理できます。
Lazyモードとは?
Lazyモードでは、データ操作の計算が蓄積され、明示的にcollect()
を呼び出すまで実行されません。この仕組みにより、以下のようなメリットがあります。
- クエリの最適化: 操作をまとめて最適化し、高速に処理。
- メモリ効率: 不要なデータ操作を削減。
- 複雑なクエリの効率化: 操作を一度に実行。
Lazyモードの使い方
Lazyモードでは、lazy()
を使ってLazyFrameを作成します。
lazy_df = df.lazy()
result = (
lazy_df
.filter(pl.col("年齢") >= 25)
.group_by("名前")
.agg(pl.col("点数").mean().alias("平均点"))
)
final_df = result.collect()
print(final_df)
shape: (2, 3)
┌──────┬──────┬──────┐
│ 名前 ┆ 年齢 ┆ 点数 │
│ --- ┆ --- ┆ --- │
│ str ┆ i64 ┆ i64 │
╞══════╪══════╪══════╡
│ 太郎 ┆ 25 ┆ 88 │
│ 花子 ┆ 30 ┆ 92 │
└──────┴──────┴──────┘
Polarsを使いこなすためのヒント
型指定でさらに効率化
Polarsは型推論を行いますが、必要に応じて明示的に指定することも可能です。
df = pl.DataFrame({
"名前": ["太郎", "花子"],
"年齢": [25, 30]
}, schema={"名前": pl.Utf8, "年齢": pl.Int32})
公式ドキュメントを活用
Polarsの公式ドキュメントは非常に詳しく、ほとんどの疑問に答えてくれます。
まとめ
Polarsは、Pythonでのデータ処理を次のレベルに引き上げるツールです。そのシンプルなインターフェースと強力な性能は、初心者から上級者まで幅広いユーザーに適しています。EagerモードとLazyモードの両方を使い分け、より効率的なデータ処理を実現してみましょう。
Polarsを使ってみた感想や、あなたの活用方法をぜひコメントで教えてください!