polars-dataframes について
polars-dataframesは、表形式データを扱うPythonユーザー向けのスキルで、Polars DataFrameライブラリを中心に解説します。式ベースの処理、遅延クエリ最適化、並列処理、データ入出力を扱います。
主な機能
- 01式ベースのDataFrame操作
- 02遅延クエリ最適化とストリーミング
- 03結合、グループ化、データ整形
- 04CSV、Parquet、JSON、データベース入出力
活用シーン
- 01表形式データのETLワークフロー構築
- 02大規模テーブルの結合と集計
- 03時系列特徴量の作成
- 04性能向上を目的としたpandasワークフローの移行
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ jaechang-hits/ sciagent-skills --skill polars-dataframesインストール後、Claude Code で/polars-dataframesを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/advanced_operations.mdio_best_practices.mdpandas_migration.md詳細
Polars DataFrames
概要
Polars は、Rust バックエンドを備え、Apache Arrow を基盤とする高性能な Python 用 DataFrame ライブラリです。式ベースの API による遅延評価と自動並列化を提供し、効率的なデータ処理、変換、分析を実現します。
使用する場面
- RAM に収まる 100 MB〜100 GB の表形式データセットを処理する場合
- 読み込み・変換・書き込みを高速に行う必要がある ETL パイプライン
- パフォーマンスが重要な場合に pandas を置き換える場合(通常 10〜100 倍の高速化)
- 自動最適化(述語/射影のプッシュダウン)を利用する遅延クエリパイプライン
- 大規模なテーブルの結合、ピボット、再構成
- Parquet、CSV、JSON、またはクラウドに保存されたデータを効率よく読み込む場合
- ウィンドウ関数や複雑なグループ集計
- RAM に収まらない大規模なデータには、代わりに Dask または Vaex を使用してください
- GPU で高速化された DataFrame には、代わりに cuDF を使用してください
前提条件
pip install polars
# Optional extras:
pip install polars[all] # All I/O backends
pip install polars[pandas] # Pandas interop
pip install polars[numpy] # NumPy interop
pip install connectorx sqlalchemy # Database connectivity
クイックスタート
import polars as pl
# Create DataFrame
df = pl.DataFrame({
"name": ["Alice", "Bob", "Charlie", "Diana"],
"dept": ["Sales", "Eng", "Sales", "Eng"],
"salary": [70000, 85000, 72000, 90000],
})
# Expression-based pipeline
result = (
df.filter(pl.col("salary") > 71000)
.with_columns(bonus=pl.col("salary") * 0.1)
.group_by("dept")
.agg(
pl.col("salary").mean().alias("avg_salary"),
pl.len().alias("count"),
)
)
print(result)
# shape: (2, 3)
# ┌───────┬────────────┬───────┐
# │ dept ┆ avg_salary ┆ count │
# ├───────┼────────────┼───────┤
# │ Eng ┆ 87500.0 ┆ 2 │
# │ Sales ┆ 72000.0 ┆ 1 │
# └───────┴────────────┴───────┘
コア API
1. DataFrame の操作
行の選択、フィルタリング、列の追加/変更、並べ替え、サンプリングを行います。
import polars as pl
df = pl.DataFrame({
"id": [1, 2, 3, 4, 5],
"name": ["Alice", "Bob", "Charlie", "Diana", "Eve"],
"age": [25, 30, 35, 28, 32],
"score": [88.5, 92.0, 76.3, 95.1, 84.7],
})
# Select columns (with computed expressions)
selected = df.select(
"name",
pl.col("age"),
(pl.col("score") / 100).alias("score_pct"),
)
print(selected.shape) # (5, 3)
# Filter rows (multiple conditions → implicit AND)
filtered = df.filter(
pl.col("age") > 27,
pl.col("score") > 80,
)
print(filtered.shape) # (3, 4) — Bob, Diana, Eve
# Add columns (preserves existing)
enriched = df.with_columns(
grade=pl.when(pl.col("score") >= 90).then(pl.lit("A"))
.when(pl.col("score") >= 80).then(pl.lit("B"))
.otherwise(pl.lit("C")),
age_months=pl.col("age") * 12,
)
print(enriched.columns)
# ['id', 'name', 'age', 'score', 'grade', 'age_months']
# Sort
df.sort("score", descending=True).head(3)
2. GroupBy と集計
行をグループ化し、要約統計量を計算します。
import polars as pl
sales = pl.DataFrame({
"region": ["East", "West", "East", "West", "East", "West"],
"product": ["A", "A", "B", "B", "A", "B"],
"revenue": [100, 150, 200, 180, 120, 210],
"units": [10, 15, 20, 18, 12, 21],
})
# Basic group_by
summary = sales.group_by("region").agg(
pl.col("revenue").sum().alias("total_rev"),
pl.col("revenue").mean().alias("avg_rev"),
pl.len().alias("n_transactions"),
)
print(summary)
# Multiple keys + conditional aggregation
by_rp = sales.group_by("region", "product").agg(
pl.col("revenue").sum(),
(pl.col("units") > 15).sum().alias("large_orders"),
)
print(by_rp)
# Window functions with over() — add group stats without collapsing rows
enriched = sales.with_columns(
region_avg=pl.col("revenue").mean().over("region"),
rank_in_region=pl.col("revenue").rank(descending=True).over("region"),
pct_of_region=pl.col("revenue") / pl.col("revenue").sum().over("region"),
)
print(enriched.select("region", "product", "revenue", "region_avg", "rank_in_region"))
3. 結合
共通キーを使用して DataFrame を結合します。
import polars as pl
customers = pl.DataFrame({
"cid": [1, 2, 3, 4],
"name": ["Alice", "Bob", "Charlie", "Diana"],
})
orders = pl.DataFrame({
"oid": [101, 102, 103, 104],
"cid": [1, 2, 1, 5],
"amount": [100, 200, 150, 300],
})
# Inner join — only matching rows
inner = customers.join(orders, on="cid", how="inner")
print(inner.shape) # (3, 4) — cid 1 (×2), cid 2
# Left join — all left rows, nulls where no match
left = customers.join(orders, on="cid", how="left")
print(left.shape) # (4, 4) — Charlie and Diana have null amount
# Anti join — left rows WITHOUT a match in right
no_orders = customers.join(orders, on="cid", how="anti")
print(no_orders["name"].to_list()) # ['Charlie', 'Diana']
# Join on different column names
customers.join(orders, left_on="cid", right_on="cid", suffix="_order")
# Asof join — match to nearest timestamp (time-series alignment)
quotes = pl.DataFrame({
"time": [1.0, 2.0, 3.0, 4.0],
"price": [100, 101, 102, 103],
}).cast({"time": pl.Float64})
trades = pl.DataFrame({
"time": [1.5, 3.2],
"qty": [50, 75],
}).cast({"time": pl.Float64})
result = trades.join_asof(quotes, on="time", strategy="backward")
print(result)
# time=1.5 matched price=100, time=3.2 matched price=102
4. 再構成
ピボット、ピボット解除、展開、転置の操作を行います。
import polars as pl
# --- Pivot (long → wide) ---
long = pl.DataFrame({
"date": ["Jan", "Jan", "Feb", "Feb"],
"product": ["A", "B", "A", "B"],
"sales": [100, 150, 120, 160],
})
wide = long.pivot(values="sales", index="date", columns="product")
print(wide)
# date | A | B
# Jan | 100 | 150
# Feb | 120 | 160
# --- Unpivot (wide → long) ---
back_to_long = wide.unpivot(
index="date", on=["A", "B"],
variable_name="product", value_name="sales",
)
print(back_to_long.shape) # (4, 3)
# --- Explode list columns ---
nested = pl.DataFrame({
"id": [1, 2],
"tags": [["a", "b", "c"], ["d", "e"]],
})
flat = nested.explode("tags")
print(flat.shape) # (5, 2)
5. データ I/O
CSV、Parquet、JSON、Excel、データベース、クラウドストレージのデータを読み書きします。
import polars as pl
# --- CSV ---
df = pl.read_csv("data.csv")
df.write_csv("output.csv")
# --- Parquet (recommended for performance) ---
df = pl.read_parquet("data.parquet")
df.write_parquet("output.parquet", compression="zstd")
# --- JSON / NDJSON ---
df = pl.read_ndjson("data.ndjson")
df.write_ndjson("output.ndjson")
# --- Excel ---
df = pl.read_excel("data.xlsx", sheet_name="Sheet1")
df.write_excel("output.xlsx")
# --- Lazy scan (preferred for large files) ---
lf = pl.scan_csv("large.csv")
result = lf.filter(pl.col("value") > 0).select("id", "value").collect()
print(result.shape)
# --- Database ---
df = pl.read_database_uri(
"SELECT * FROM users WHERE age > 25",
uri="postgresql://user:pass@localhost/db",
)
# --- Cloud storage (S3, GCS, Azure) ---
df = pl.read_parquet("s3://bucket/data.parquet")
df = pl.scan_parquet("gs://bucket/data/*.parquet").collect()
# --- Partitioned Parquet (Hive-style) ---
df.write_parquet("output_dir", partition_by=["year", "month"])
lf = pl.scan_parquet("output_dir/**/*.parquet")
6. 式 API
文字列、日時、リスト、条件に関する操作を行います。
import polars as pl
from datetime import date
df = pl.DataFrame({
"text": ["Hello World", "foo bar", "POLARS"],
"dt": [date(2023, 1, 15), date(2023, 6, 30), date(2024, 12, 1)],
"values": [[1, 2, 3], [4, 5], [6]],
})
# String operations
strings = df.select(
lower=pl.col("text").str.to_lowercase(),
length=pl.col("text").str.len_chars(),
contains_o=pl.col("text").str.contains("o"),
split=pl.col("text").str.split(" "),
)
print(strings)
# Datetime operations
dates = df.select(
year=pl.col("dt").dt.year(),
month=pl.col("dt").dt.month(),
weekday=pl.col("dt").dt.weekday(),
quarter=pl.col("dt").dt.quarter(),
)
print(dates)
# List operations
lists = df.select(
list_len=pl.col("values").list.len(),
list_sum=pl.col("values").list.sum(),
first=pl.col("values").list.first(),
)
print(lists)
# Conditional expressions (when/then/otherwise)
df = pl.DataFrame({"score": [45, 72, 88, 95, 60]})
result = df.with_columns(
grade=pl.when(pl.col("score") >= 90).then(pl.lit("A"))
.when(pl.col("score") >= 80).then(pl.lit("B"))
.when(pl.col("score") >= 70).then(pl.lit("C"))
.otherwise(pl.lit("F")),
)
print(result)
# Null handling
df2 = pl.DataFrame({"x": [1, None, 3, None, 5]})
filled = df2.with_columns(
filled=pl.col("x").fill_null(0),
forward=pl.col("x").fill_null(strategy="forward"),
is_null=pl.col("x").is_null(),
)
print(filled)
# Multi-column operations with regex selector
df3 = pl.DataFrame({"val_a": [1, 2], "val_b": [3, 4], "name": ["x", "y"]})
doubled = df3.select(pl.col("^val_.*$") * 2)
print(doubled)
7. 遅延評価
実行前に最適化されたクエリプランを構築します。
import polars as pl
# Lazy mode: build plan, optimize, then execute
lf = pl.scan_csv("large_dataset.csv")
result = (
lf
.select("user_id", "category", "amount", "date") # projection pushdown
.filter(pl.col("amount") > 100) # predicate pushdown
.with_columns(pl.col("date").str.to_date())
.group_by("category")
.agg(
pl.col("amount").sum().alias("total"),
pl.col("user_id").n_unique().alias("unique_users"),
)
.sort("total", descending=True)
)
# Inspect the optimized plan
print(result.explain())
# Execute
df = result.collect()
print(df)
# Streaming mode for very large data
lf = pl.scan_parquet("data/*.parquet")
result = (
lf
.filter(pl.col("year") >= 2023)
.group_by("region")
.agg(pl.col("sales").sum())
.collect(streaming=True) # processes in batches
)
print(result)
# Sink directly to file (no full materialization)
lf.filter(pl.col("active")).sink_parquet("filtered_output.parquet")
主な概念
遅延評価と即時評価の比較
| 項目 | 即時評価(DataFrame) | 遅延評価(LazyFrame) |
|---|---|---|
| 作成方法 | pl.read_*()、pl.DataFrame() | pl.scan_*()、df.lazy() |
| 実行 | 即時 | .collect() の実行時 |
| 最適化 | なし | 述語/射影のプッシュダウン、結合の並べ替え |
| ストリーミング | なし | collect(streaming=True) |
| 適した用途 | 小規模データ、対話的な処理 | 大規模データ、パイプライン |
Polars のデータ型
| 型 | Python の相当型 | 備考 |
|---|---|---|
Int8/16/32/64 | int | 必要十分な最小サイズを選択します |
UInt8/16/32/64 | int | 符号なし |
Float32/64 | float | デフォルトは Float64 |
Boolean | bool | |
Utf8 | str | 文字列型 |
Categorical | — | カーディナリティの低い文字列(groupby が高速) |
Date | datetime.date | 時刻を含まない日付 |
Datetime | datetime.datetime | マイクロ秒精度 |
Duration | datetime.timedelta | 時間差 |
List | list | 可変長リスト |
Struct | dict | 名前付きフィールド |
Null | None | すべての値が null の列 |
Pandas との主な違い
- インデックスなし:行には位置でのみアクセスします。ラベルを使った
.loc/.ilocはありません - 厳密な型付け:暗黙的な型変換は行われません。明示的に
.cast()を指定する必要があります - メソッドではなく式:
df["x"].mean()ではなくpl.col("x").mean()を使用します - デフォルトで並列処理:すべての列操作が並列で実行されます
- 遅延評価:クエリ最適化のために
LazyFrameで利用できます
一般的なワークフロー
1. ETL パイプライン(CSV → クリーンアップ → Parquet)
import polars as pl
# Extract
lf = pl.scan_csv(
"raw_data.csv",
dtypes={"id": pl.Int64, "date": pl.Utf8, "amount": pl.Float64},
)
# Transform
cleaned = (
lf
.with_columns(pl.col("date").str.to_date("%Y-%m-%d"))
.filter(pl.col("amount").is_not_null())
.with_columns(
year=pl.col("date").dt.year(),
month=pl.col("date").dt.month(),
amount_log=pl.col("amount").log(),
)
.drop_nulls()
)
# Load
cleaned.collect().write_parquet("clean_data.parquet", compression="zstd")
print("ETL complete")
2. 複数ソースの結合と集計
import polars as pl
# Simulate three data sources
users = pl.DataFrame({
"uid": [1, 2, 3, 4],
"name": ["Alice", "Bob", "Charlie", "Diana"],
"region": ["East", "West", "East", "West"],
})
orders = pl.DataFrame({
"oid": range(1, 7),
"uid": [1, 1, 2, 3, 3, 3],
"amount": [100, 200, 150, 50, 75, 125],
})
products = pl.DataFrame({
"oid": range(1, 7),
"category": ["Elec", "Books", "Elec", "Books", "Elec", "Elec"],
})
# Join → aggregate
result = (
orders
.join(users, on="uid", how="left")
.join(products, on="oid", how="left")
.group_by("region", "category")
.agg(
pl.col("amount").sum().alias("total"),
pl.col("amount").mean().alias("avg_order"),
pl.len().alias("n_orders"),
)
.sort("total", descending=True)
)
print(result)
3. 時系列の特徴量エンジニアリング
使用する機能:GroupBy、ウィンドウ関数、結合、式 API。
pl.scan_csv()またはpl.scan_parquet()で時系列データを読み込みます- 日付を解析します:
.with_columns(pl.col("date").str.to_date()) - エンティティと日付で並べ替えます:
.sort("entity_id", "date") - ラグ特徴量を追加します:
pl.col("value").shift(n).over("entity_id") - 移動統計量を追加します:
pl.col("value").rolling_mean(window_size=7).over("entity_id") - 変化率を計算します:
(pl.col("value") - pl.col("value").shift(1)) / pl.col("value").shift(1) - データを収集して書き込みます:
.collect().write_parquet("features.parquet")
主なパラメーター
| パラメーター | 関数 | デフォルト | 範囲/オプション | 効果 |
|---|---|---|---|---|
how | .join() | "inner" | inner, left, outer, cross, semi, anti | 結合の種類 |
strategy | .join_asof() | "backward" | backward, forward, nearest | Asof マッチングの方向 |
streaming | .collect() | False | True/False | 大規模データをバッチ単位で処理します |
compression | .write_parquet() | "zstd" | snappy, gzip, brotli, lz4, zstd, uncompressed | Parquet の圧縮 |
partition_by | .write_parquet() | None | 列のリスト | Hive スタイルのパーティション分割 |
rechunk | pl.concat() | False | True/False | 結合後にメモリを再チャンク化します |
aggregate_function | .pivot() | "first" | first, sum, mean, max, min, count | ピボット時の重複の処理 |
n_rows | pl.read_csv() | None | 正の整数 | 読み込む行数を制限します(サンプリング用) |
parallel | pl.read_csv() | "auto" | auto, columns, row_groups, none | 並列読み込みの方法 |
dtypes | pl.read_csv() | None | 列→型の辞書 | 型推論を上書きします |
ベストプラクティス
-
大規模なデータセットには遅延モードを使用する:
pl.read_csv()ではなくpl.scan_csv()を使用します。クエリの最適化とストリーミングが可能になります。 -
式 API を使い続ける:
.map_elements()は避けてください(Python を実行するため、並列処理されません)。Polars のネイティブ操作を優先してください。文字列、日時、リストの名前空間でほとんどのニーズに対応できます。 -
早い段階で選択し、早い段階でフィルターする:遅延パイプラインでは、できるだけ早く
.select()と.filter()を配置します。オプティマイザーによって下方にプッシュできますが、明示的に配置すると役立ちます。 -
カーディナリティの低い文字列には Categorical を使用する:
df.with_columns(pl.col("region").cast(pl.Categorical))— 繰り返し出現する文字列値を使った groupby と結合が大幅に高速化します。 -
CSV より Parquet を優先する:Parquet は型を保持し、述語プッシュダウンをサポートし、ファイルサイズを 5~10 分の 1 にできます。圧縮率と速度のバランスを重視する場合は
compression="zstd"を使用します。 -
アンチパターン — 行を対象とした Python ループ:計算のために
for row in df.iter_rows()で行を反復処理しないでください。代わりに式を使用します。 -
アンチパターン —
.with_columns()呼び出しの連鎖:複数の列の追加は 1 回の.with_columns()呼び出しにまとめ、並列実行できるようにします。
よく使うレシピ
レシピ:Pandas からの移行パターン
import polars as pl
import pandas as pd
# Convert pandas → polars
pd_df = pd.DataFrame({"col": [1, 2, 3], "group": ["a", "b", "a"]})
pl_df = pl.from_pandas(pd_df)
# Key operation mapping:
# pandas: df["col"] → polars: df.select("col")
# pandas: df[df["col"] > 1] → polars: df.filter(pl.col("col") > 1)
# pandas: df.assign(x=...) → polars: df.with_columns(x=...)
# pandas: df.groupby().agg() → polars: df.group_by().agg()
# pandas: df.groupby().transform → polars: pl.col(...).over(...)
# pandas: df.merge() → polars: df.join()
# pandas: df.melt() → polars: df.unpivot()
# Convert back
pd_result = pl_df.to_pandas()
レシピ:複雑な集計レポート
import polars as pl
df = pl.DataFrame({
"dept": ["Sales", "Eng", "Sales", "Eng", "Sales", "Eng"],
"level": ["Jr", "Sr", "Sr", "Jr", "Jr", "Sr"],
"salary": [50000, 95000, 75000, 70000, 55000, 100000],
})
report = (
df.group_by("dept", "level")
.agg(
pl.col("salary").mean().alias("avg_sal"),
pl.col("salary").median().alias("med_sal"),
pl.col("salary").std().alias("std_sal"),
pl.len().alias("count"),
)
.pivot(values="avg_sal", index="dept", columns="level")
.with_columns(
diff=pl.col("Sr") - pl.col("Jr"),
)
)
print(report)
レシピ:スキーマを揃えて複数ファイルを読み込む
import polars as pl
from pathlib import Path
# Read multiple CSVs with potentially different columns
files = sorted(Path("data/").glob("*.csv"))
dfs = [pl.read_csv(f) for f in files]
# Diagonal concat handles mismatched schemas (fills nulls)
combined = pl.concat(dfs, how="diagonal")
print(f"Combined: {combined.shape}")
print(f"Columns: {combined.columns}")
# Or use lazy scan for Parquet (automatic parallel)
lf = pl.scan_parquet("data/**/*.parquet")
result = lf.filter(pl.col("date") > "2023-01-01").collect()
トラブルシューティング
| 問題 | 原因 | 解決策 |
|---|---|---|
SchemaError: column not found | 列名のタイプミス、または大文字と小文字の不一致 | df.columns を確認してください。Polars では大文字と小文字が区別されます |
ComputeError: cannot cast | 操作での型の不一致 | .cast(pl.Type) を明示的に使用します |
collect 時の OutOfMemoryError | データが大きすぎて一括処理できない | lf.collect(streaming=True) を使用するか、先にフィルターします |
.map_elements() が遅い | Python の UDF が並列処理を妨げている | ネイティブの式(str/dt/list の名前空間)を使って書き換えます |
| 結合結果の行数が予想より多い | 右側の DataFrame に重複キーがある | 先に重複を削除します:df.unique(subset=["key"]) |
InvalidOperationError: join on different types | キー列の dtypes が異なる | 両方を同じ型にキャストします:.cast(pl.Int64) |
.over() が誤った値を返す | すべてのグループ列を含め忘れている | .over("col1", "col2") にすべてのグループ列を含めます |
| Parquet ファイルを読み取れない | 互換性のない圧縮方式で書き込まれている | 最大限の互換性を確保するには compression="snappy" を指定します |
| CSV の日付が文字列として読み込まれる | CSV リーダーでは日付が自動解析されない | 読み込み後に解析します:pl.col("date").str.to_date("%Y-%m-%d") |
concat が異なるスキーマで失敗する | DataFrame 間で列が一致していない | how="diagonal" を使用して、不足している列を null で埋めます |
同梱リソース
-
references/pandas_migration.md— Pandas から Polars への移行ガイドです。操作の対応表(選択、フィルタリング、列操作、集計、ウィンドウ関数、結合、形状変更、文字列操作、日時操作、欠損データ、I/O)、相互運用コード、一般的な移行パターンのコード比較、移行時の注意点、移行チェックリストを掲載しています。- 対象範囲:元の pandas_migration.md に含まれるすべての操作対応表
- 本文へ移動:pandas との主な違いの概要 → SKILL.md の Key Concepts「Key Differences from Pandas」セクション、基本的な変換レシピ → SKILL.md の Common Recipes「Pandas Migration Pattern」
- 省略:行の反復処理と逐次 pipe のアンチパターンコード例(io_best_practices.md で説明)
-
references/advanced_operations.md— ローリングウィンドウ(時間ベースと行ベース)、累積操作(cum_sum/max/min/prod)、グループ化コンテキストでの shift/lag/lead、struct 操作(作成、アクセス、unnest)、リスト列の操作(統計、eval、filter、explode)、一意性/重複の検出、高度な並べ替え(nulls_last、式ベース、グループごとの上位 N 件)、列名の変更(辞書、サフィックス/プレフィックス、プログラムによる変更)、サンプリング(固定 n、割合、ブートストラップ)、転置、高度な形状変更パターン(ワイドからロング、ネストした JSON のフラット化、複数レベルの unpivot、水平方向の連結)を扱います。- 対象範囲:元の operations.md に含まれる高度な操作、およびメインの SKILL.md に含まれない元の transformations.md の変換
- 本文へ移動:基本的な選択/フィルタリング → SKILL.md の Core API セクション 1、groupby/集計 → セクション 2、基本的な結合/asof → セクション 3、基本的な pivot/unpivot/explode/concat → セクション 4、文字列/日付/リスト/条件式の基本 → セクション 6、基本的なウィンドウ関数 → セクション 2
- 省略:結合のパフォーマンスに関するヒント(簡潔なため、SKILL.md の Best Practices で説明)、連結オプション(rechunk は Key Parameters の表で説明)
-
references/io_best_practices.md— I/O 形式の完全ガイド(CSV オプション、パーティショニングを含む Parquet オプション、JSON/NDJSON、複数シートの Excel、Arrow IPC)、データベース接続(PostgreSQL、MySQL、SQLite、BigQuery)、クラウドストレージ(S3、Azure、GCS)、メモリ内形式の変換(dict、NumPy、pandas、Arrow)、形式選択の判断ガイド、スキーマ管理とエラー処理、式の構成と再利用パターン、列選択パターン(型、正規表現、除外による選択)、メモリ管理(estimated_size、型の最適化、ストリーミング)、合成可能な変換のためのパイプライン関数、テスト/デバッグ(クエリプラン、スキーマ検証、プロファイリング)、パフォーマンスのアンチパターン(逐次 pipe、多数の DataFrame、インプレース変更、型の未指定)、バージョン互換性に関する注意事項を扱います。- 対象範囲:元の io_guide.md に含まれるすべての I/O 内容、元の best_practices.md に含まれる式/メモリ/テスト/パフォーマンスに関する内容、元の core_concepts.md に含まれる形式選択とバージョンに関する注意事項
- 本文へ移動:CSV/Parquet/JSON/Excel/データベースの基本的な読み書き → SKILL.md の Core API セクション 5、lazy と eager の比較 → SKILL.md の Key Concepts の表、基本的な式のコンテキスト/構文 → SKILL.md のセクション 6、並列化/型システムの概念 → SKILL.md の Key Concepts と Best Practices、null の処理 → SKILL.md のセクション 6、Categorical の推奨事項 → SKILL.md の Best Practices 項目 4
- 省略:式の詳細な基礎(式とは何か、式のコンテキスト)— SKILL.md の Core API で完全に説明、基本的な条件ロジックの例 — セクション 6 で説明、基本的な集計パターン — セクション 2 で説明
参照ファイルごとの処置(元の6ファイル)
| 元のファイル | 行数 | 処置 | 移行先 |
|---|---|---|---|
operations.md | 603 | 統合 | 高度な操作 → references/advanced_operations.md;基本的な選択/フィルター/groupby/ウィンドウ/文字列/日付 → SKILL.md コア API セクション 1~2、6 |
transformations.md | 550 | 統合 | 形状変更/転置 → references/advanced_operations.md;基本的な結合/ピボット/ピボット解除/展開/連結 → SKILL.md コア API セクション 3~4 |
io_guide.md | 558 | 統合 | I/O の詳細全般 → references/io_best_practices.md;基本的な読み込み/書き込み → SKILL.md コア API セクション 5 |
best_practices.md | 650 | 統合 | 式の再利用、メモリ、テスト、アンチパターン → references/io_best_practices.md;基本的なベストプラクティス → SKILL.md のベストプラクティス |
core_concepts.md | 379 | 統合 | フォーマットの選択、バージョンに関する注意事項 → references/io_best_practices.md;データ型、遅延/即時実行、並列処理 → SKILL.md の主な概念 |
pandas_migration.md | 418 | 移行 | → references/pandas_migration.md(ウィンドウ/文字列/日時/欠損データの表を追加して拡充) |
意図的な省略
- 行の反復処理の例(operations.md):有用な機能としては記載せず、ベストプラクティスでアンチパターンとしてのみ言及
- 式の基礎チュートリアル(core_concepts.md):式の構文、コンテキスト、展開については SKILL.md のコア API セクションで網羅しているため、別途チュートリアルを設けると重複します
- 並列化の内部に関する詳細(core_concepts.md):「並列化される処理」の一覧は省略しました。ユーザーには、式 API を使い続けるためのベストプラクティスに関するガイダンスのみが必要です
- コピーオンライトの比較(core_concepts.md):Pandas 2.0 以降のコピーオンライトの詳細は省略しました。これは移行に関する内容であり、Polars を中心とした内容ではありません
関連スキル
- zarr-python — チャンク化配列ストレージ;Polars で読み書きした Parquet を Zarr で処理できます
- matplotlib-scientific-plotting — 可視化;プロットには
.to_pandas()で pandas に変換します - scikit-learn-machine-learning — ML パイプライン;sklearn への入力には
.to_numpy()または.to_pandas()を使用します
参考資料
- Polars ユーザーガイド:https://docs.pola.rs/
- Polars API リファレンス:https://docs.pola.rs/api/python/stable/reference/
- GitHub:https://github.com/pola-rs/polars
- Polars クックブック:https://docs.pola.rs/user-guide/