Polarsで始める高速データ処理: Pythonユーザーのための入門ガイド

データ分析や処理の速度がボトルネックになっていませんか?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 を使用します。これにより、データに対する柔軟な条件付きの変換が可能です。

基本構文

  1. when: 条件を指定します。
  2. then: 条件が満たされた場合に返す値を指定します。
  3. 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を使ってみた感想や、あなたの活用方法をぜひコメントで教えてください!

上部へスクロール