Polars基本メソッド説明集
はじめに:Polarsの特徴とメソッドチェーン
Polarsの最大の特徴は、メソッドチェーンで処理を繋げられることです。データの読み込みから変換、フィルタリング、集計まで、一連の処理を直感的に記述できます。
基本的なメソッドチェーンの例
import polars as pl
df_sales = pl.read_csv('sales.csv') # 1. 読み込み
# 一連の処理を実行
(df_sales
.filter(pl.col('price') > 0) # 4. 抽出(3.判定系使用)
.with_columns( # 8. 追加
# 7. 条件分岐(3.判定系使用)
pl.when(pl.col('price') > 1000).then('高額').otherwise('通常')
.alias('price_category') # 9. その他(列名変更)
)
.group_by('price_category') # 10. グループ化
.agg(pl.col('price').mean()) # 10. グループ化(6.計算系)
.sort('price', descending=True) # 9. その他(並び替え)
.head(10) # 2. 最終確認
)
- コツ1:括弧でメソッド全体を囲むことで複数行に分けて書く
- コツ2:各メソッドの前に改行を入れる
- コツ3:インデントを揃えて可読性を高める
- コツ4:適宜コメントアウトしながら途中経過を確認する
1. データ読み込み
pl.read_csv()
CSVファイルを読み込んでDataFrameを作成します。ここからメソッドチェーンが始まります。
df = pl.read_csv('data.csv', schema_overrides=dtypes, encoding='utf-8-sig')
2. データ確認(データの把握・最終確認)
head()
データフレームの先頭から指定した行数を表示します。
df.head(3) # 先頭3行を表示
# 使用例
(df_sales
.filter(pl.col('price') > 100)
.head(5)
)
tail()
データフレームの末尾から指定した行数を表示します。
df.tail(3) # 末尾3行を表示
# 使用例
(df_orders
.sort('order_date')
.tail(10) # 日付順に並べて最新10件
)
shape
データフレームの形状(行数、列数)を取得します。
df.shape # (行数, 列数)のタプルを返す
# 使用例(shapeはプロパティなのでチェーンの最後に使用する)
(df_status
.filter(pl.col('status') == 'active')
.shape # メソッドではないので括弧も不要
)
null_count()
各列の欠損値の数を確認します。
df.null_count()
# 使用例
(df_products
.select('price', 'quantity')
.null_count()
)
unique()
指定した列のユニークな値を取得します。
df.select(pl.col('color')).unique()
# 使用例
(df_inventory
.filter(pl.col('price') > 100)
.select('category')
.unique()
)
sample()
データからランダムサンプリングを行います。
df.sample(n=10) # 10件をランダムに抽出
df.sample(fraction=0.05) # 5%をランダムに抽出
# 使用例
(df_electronics
.filter(pl.col('category') == 'Electronics')
.sample(n=100)
.sort('price')
)
3. 判定系(条件を作る)
数値比較
基本的な数値の比較演算子です。
pl.col('price') > 1000 # 1000より大きいという条件
pl.col('price') <= 500 # 500以下という条件
pl.col('price') == 1000 # 1000であるという条件
pl.col('price') != 0 # 0ではないという条件
# 使用例
(df_items
.filter(pl.col('price') >= 500)
)
str.contains()
文字列に特定の文字が含まれているかチェックします。
pl.col('city').str.contains('東京')
# 使用例
(df_location
.filter(pl.col('city').str.contains('東京'))
.group_by('district')
.agg(pl.col('sales').sum())
.sort('sales', descending=True)
)
str.starts_with()
文字列が特定の文字で始まるかチェックします。
pl.col('product_code').str.starts_with('A')
# 使用例
(df_products
.filter(pl.col('product_code').str.starts_with('A'))
.select('product_code', 'product_name', 'price')
.sort('product_code')
)
is_between()
値が指定した範囲内にあるかチェックします。
pl.col('score').is_between(80, 100)
# 使用例
(df_scores
.filter(pl.col('score').is_between(80, 100))
)
is_null(), is_not_null()
欠損値の有無をチェックします。
pl.col('email').is_null()
pl.col('email').is_not_null()
# 使用例
(df_customers
.filter(pl.col('email').is_not_null())
)
& (AND演算子)
複数の条件を結合してチェックします。
(pl.col('price') >= 100) & (pl.col('stock') > 0)
# 使用例
(df_active
.filter(
(pl.col('price') > 0) &
(pl.col('stock') > 0) &
(~pl.col('status').str.contains('廃止'))
)
.sort('price')
)
| (OR演算子)
複数の条件のいずれかが満たされるかをチェックします。
シフトを押しながらキーボードの右上にある該当するキーをクリックすると入力できます。
(pl.col('category') == 'Electronics') | (pl.col('category') == 'Books')
# 使用例
(df_multiple_categories
.filter(
(pl.col('category') == 'Electronics') |
(pl.col('category') == 'Books') |
(pl.col('price') > 1000)
)
.sort('price', descending=True)
)
~ (NOT演算子)
条件を否定します。
~pl.col('status').str.contains('無効') # "無効"が含まれていないかどうかをチェックする
# 使用例
(df_filtered
.filter(~pl.col('product_code').str.starts_with('A')) # Aから始まらない行を抽出
)
4. 抽出系(行・列を絞る)
filter()
条件に基づいて行を抽出します。
df.filter(pl.col('price') >= 500)
# 使用例
(df_expensive
.filter(pl.col('price') >= 1000)
.filter(pl.col('stock') > 0)
.select('product_name', 'price')
.sort('price', descending=True)
)
select()
指定した列を抽出します。
df.select('price') # 1列を選択
df.select('name','age') # 複数列を選択
# 使用例
(df_active
.filter(pl.col('status') == 'active')
.select('product_name', 'price', 'category')
.sort('price')
)
drop()
指定した列を削除します。
df.drop('unwanted_column') # 1列を削除
df.drop('col1', 'col2', 'col3') # 複数列を削除
# 使用例
(df_clean
.drop('temp_id', 'internal_notes', 'debug_info')
.filter(pl.col('is_valid') == True)
)
5. 変換系(データの型を変える)
cast()(さまざまな型の変換が可能)
データ型を変換します。本講義では「数値型→文字列型」に利用します。
pl.col('order_id').cast(str) # 数値型から文字列型に変換
# 使用例
(df_orders
.with_columns(
pl.col('order_date').cast(str)
)
.filter(pl.col('order_date').str.starts_with('2024'))
)
str.strptime()(文字列→日付の型変換)
文字列型を日付型に変換します。
pl.col('order_date').str.strptime(pl.Date, "%Y%m%d") # Yは年、mは月、dは日
# 使用例
(df_orders
.with_columns(
pl.col('order_date').str.strptime(pl.Date, "%Y%m%d")
)
.filter(pl.col('order_date') >= pl.date(2024, 1, 1))
.sort('order_date')
)
dt.strftime()(日付→文字列の型変換)
日付型を文字列型に変換します。
pl.col('order_date').dt.strftime('%Y%m%d') # Yは年、mは月、dは日
# 使用例
(df_monthly
.with_columns(
pl.col('order_date').dt.strftime('%Y%m%s').alias('date')
)
.group_by('date')
.agg(pl.col('sales').sum())
)
dt.day()
日付から「日」の部分を数値で取得します。
pl.col('order_date').dt.day() # 日付から日を抽出(1-31)
# 使用例
(df_orders
.with_columns(
pl.col('order_date').dt.day().alias('day')
)
.filter(pl.col('day') <= 15) # 月の前半のデータのみ抽出
)
dt.month()
日付から「月」の部分を数値で取得します。
pl.col('order_date').dt.month() # 日付から月を抽出(1-12)
# 使用例
(df_orders
.with_columns(
pl.col('order_date').dt.month().alias('month')
)
.filter(pl.col('month').is_in([6, 7, 8])) # 夏季(6-8月)のデータのみ抽出
)
dt.weekday()
日付から「曜日」を数値で取得します。
pl.col('order_date').dt.weekday() # 曜日を数値で取得(月曜=1, 日曜=7)
# 使用例
(df_orders
.with_columns(
pl.col('order_date').dt.weekday().alias('weekday')
)
.filter(pl.col('weekday').is_in([6, 7])) # 土日のデータのみ抽出
)
6. 計算系(数値を計算する)
四則演算
基本的な算術演算子です。
pl.col('price') + pl.col('tax') # 加算
pl.col('revenue') - pl.col('cost') # 減算
pl.col('price') * pl.col('quantity') # 乗算
pl.col('profit') / pl.col('revenue') # 除算
pl.col('score') // 10 # 整数除算
# 使用例
(df_profits
.with_columns(
(pl.col('revenue') - pl.col('cost')).alias('profit'),
((pl.col('revenue') - pl.col('cost')) / pl.col('revenue')).alias('profit_rate')
)
.filter(pl.col('profit') > 0)
.sort('profit_rate', descending=True)
)
集計・数学関数
pl.len() # 行数カウント
pl.col('price').sum() # 合計値
pl.col('price').mean() # 平均値
pl.col('order_date').max() # 最大値
pl.col('order_date').min() # 最小値
pl.col('price').std() # 標準偏差
pl.col('order_date').n_unique() # ユニーク数
pl.col('category').first() # 最初の値
pl.col('target').abs() # 絶対値
(pl.col('price') * 1.08).floor() # 小数点切り捨て
# 使用例
(df_analytics
.filter(pl.col('status') == 'completed')
.group_by('region')
.agg(
pl.col('sales').sum().alias('total_sales'),
pl.col('sales').mean().alias('avg_sales'),
pl.col('customer_id').n_unique().alias('unique_customers'),
pl.len().alias('transaction_count')
)
.sort('total_sales', descending=True)
)
7. 条件分岐系(場合分けして値を決める)
pl.when(判定系).then().otherwise()
判定系を用いて条件分岐を行います。
# 1000より大きければ1、そうでなければ0とする場合
pl.when(pl.col('price') > 1000).then(1).otherwise(0)
# 複数の条件分岐を繋げることも可能
pl.when(pl.col('region').str.contains('関東')).then(1)
.when(pl.col('region').str.contains('関西')).then(2)
.otherwise(0)
# 使用例
(df_categories
.with_columns(
pl.when(pl.col('price') >= 1000).then('高額商品')
.when(pl.col('price') >= 500).then('中額商品')
.otherwise('低額商品')
.alias('price_category')
)
.group_by('price_category')
.agg(pl.len().alias('count'))
.sort('count', descending=True)
)
8. 追加系(新しい列を作る)
with_columns()
新しい列を追加または既存の列を変更します。変換系、計算系、条件分岐系を組み合わせて使用します。
# totalという列名で追加する場合
df.with_columns(
(pl.col('price') * pl.col('quantity')).alias('total')
)
# 使用例
(df_enhanced
.with_columns(
(pl.col('price') * pl.col('quantity')).alias('total_amount'), # 計算系
(pl.col('price') * 1.1).alias('price_with_tax'), # 計算系
pl.col('order_date').dt.strftime('%Y-%m').alias('order_month'), # 変換系
pl.when(pl.col('price') > 1000).then('高額').otherwise('通常').alias('category') # 条件分岐系
)
.filter(pl.col('total_amount') > 1000)
.sort('total_amount', descending=True)
)
9. その他
shift()(ずらす操作)
データを指定した行数分シフトします(ラグ機能)。
pl.col('sales').shift(1) # 1行分うしろにずらす
pl.col('sales').shift(2) # 2行分うしろにずらす
# 使用例
(df_timeseries
.sort('date')
.with_columns(
pl.col('sales').shift(1).alias('prev_sales'),
(pl.col('sales') - pl.col('sales').shift(1)).alias('sales_change')
)
.filter(pl.col('sales_change').is_not_null())
.select('date', 'sales', 'prev_sales', 'sales_change')
)
drop_nulls(), fill_null()(欠損値処理)
欠損値を削除または指定した値で埋めます。
df.drop_nulls() # いずれかの列に欠損値がある行を削除
pl.col('discount').fill_null(0) # 欠損値を0にする
# 使用例
(df_cleaned
.drop_nulls()
.filter(pl.col('price') > 0)
.sort('order_date')
)
alias()
列名に別名を付けます。複雑な計算の列を生成を生成した場合は別名をつけないとエラーになることも。
pl.col('order_date').alias('purchase_date')
# 使用例
(df_renamed
.with_columns(
(pl.col('price') * 1.1).alias('price_with_tax')
)
.select('product', 'price', 'price_with_tax')
)
pl.col()
列に対していろいろなメソッドを適用するための関数です。
pl.col('price') # 列を操作対象として指定
pl.col('price').sum() # 列に対して合計を計算
# 使用例
(df_converted
.with_columns(
pl.col('price').cast(pl.Float64).alias('price_float')
)
.select('product', 'price_float')
)
sort()
データフレームを指定した列で並び替えます。
df.sort('price') # 昇順
df.sort('price', descending=True) # 降順
df.sort('category', 'price') # 複数列で並び替え
# 使用例
(df_ranking
.filter(pl.col('stock') > 0)
.sort('sales_count', descending=True)
.head(10)
.select('product_name', 'sales_count', 'price')
)
10. グループ化系(グループごとに計算する)
group_by()
指定した列でデータをグループ化します。
df.group_by('category') # 単一列でグループ化
df.group_by('category', 'brand') # 複数列でグループ化
# 使用例(group_byの後は必ずaggが必要)
(df_summary
.filter(pl.col('price') > 0)
.group_by('category')
.agg(
pl.col('price').mean().alias('avg_price'),
pl.col('sales').sum().alias('total_sales'),
pl.len().alias('product_count')
)
.sort('total_sales', descending=True)
)
agg()
グループ化後に集計を行います。計算系や判定系を組み合わせて使用します。
df.group_by('category').agg(
pl.col('price').sum(), # 計算系:グループ毎に合計値を抽出
pl.col('stock').mean() # 計算系:グループ毎に平均値を抽出
)
# 使用例
(df_report
.with_columns(
pl.col('order_date').dt.strftime('%Y-%m').alias('month')
)
.group_by('month')
.agg(
pl.col('revenue').sum().alias('total_revenue'),
pl.col('order_id').n_unique().alias('order_count')
)
.sort('month')
)
# 高度な使用例:判定系と計算系の組み合わせ
(df_report
.group_by('category')
.agg(
pl.col('price').filter(pl.col('stock') > 100).max() # 判定系 + 計算系
)
)
len()(集計関数として)
グループ内の行数をカウントします。
df.group_by('category').len()
11. データ結合(複数テーブルの統合)
join()
データフレーム同士を結合します。
df1.join(df2, how='inner', on='product_id') # 内部結合
df1.join(df2, how='left', on='product_id') # 左結合
df1.join(df2, how='full', on='product_id') # 外部結合
# 使用例
(df_sales
.join(df_products, on='product_id', how='left')
.join(df_categories, on='category_id', how='left')
.filter(pl.col('sales_amount') > 100)
.group_by('category_name')
.agg(pl.col('sales_amount').sum().alias('total_sales'))
.sort('total_sales', descending=True)
)
12. データ変形
pivot()
データをピボットテーブル形式に変換します。縦長データを横長データ(クロス集計表)に変換する機能です。
pivot()の仕組み:
-
index: 行(縦軸)にしたい列を指定 -
on: 列(横軸)にしたい列を指定 -
values: 各セルに配置する値の列を指定
実行前データ
| month | region | sales |
|---|---|---|
| 1月 | 東京 | 100 |
| 1月 | 大阪 | 80 |
| 2月 | 東京 | 120 |
| 2月 | 大阪 | 90 |
| 3月 | 東京 | 110 |
| 3月 | 大阪 | 95 |
df.pivot(values='sales', index='month', on='region') # 実行すると以下の形になる
実行後データ
| month | 東京 | 大阪 |
|---|---|---|
| 1月 | 100 | 80 |
| 2月 | 120 | 90 |
| 3月 | 110 | 95 |
# 使用例
(df_pivot
.filter(pl.col('year') == 2024)
.group_by('month', 'region')
.agg(pl.col('sales').sum())
.pivot(values='sales', index='month', on='region')
.sort('month')
)
13. データ出力・可視化
to_pandas()
Polars形式からPandas形式に変換します。グラフ作成にあたって必ず最初に必要となる処理です。
df.to_pandas() # matplotlib用に変換する
# 使用例(可視化前の準備)
(df_chart
.group_by('month')
.agg(pl.col('revenue').sum())
.sort('month')
.to_pandas() # matplotlibで使用するためPandasに変換
)
Matplotlib(可視化)
基本設定
import matplotlib.pyplot as plt
plt.rcParams['font.family'] = ['IPAexGothic'] # 日本語フォント設定
可視化の流れ
# Polarsでデータを準備してからPndasに変換してmatplotlibで可視化
(df.group_by('category')
.agg(pl.col('sales').sum())
.sort('sales', descending=True)
.to_pandas() # matplotlib用にPandasに変換
.plot(kind='bar', x='category', y='sales', figsize=(10, 6))
)
# 細かいグラフの調整は括弧の外で行う
plt.title('カテゴリ別売上')
plt.xlabel('カテゴリ')
plt.ylabel('売上金額')
plot()
グラフを作成します。
df.plot(kind='bar', x='category', y='sales') # 棒グラフ(yの指定は省略可)
df.plot(kind='line', x='month', y='revenue') # 折れ線グラフ(yの指定は省略可)
df.plot(kind='bar', stacked=True) # 積み上げ棒グラフ
グラフオプション
この他にもさまざまなグラフオプションが選べます。
# 棒グラフのオプション
df.plot(kind='bar', x='region', figsize=(6,4), rot=45)
# 折れ線グラフのオプション
df.plot(kind='line', marker='o', linestyle='--')
グラフの装飾
plt.title(), plt.xlabel(), plt.ylabel()
グラフのタイトルと軸ラベルを設定します。
plt.title('売上推移')
plt.xlabel('月')
plt.ylabel('売上金額')
plt.subplots()
複数軸のグラフを作成することも可能です。まずはグラフエリアとプロットエリアを生成します。
legend()
凡例を設定します。
plt.legend('売上', loc='upper right')
twinx()
右側のY軸を基準とするグラフを追加します。
ax2 = ax1.twinx()
# 使用例
fig, ax1 = plt.subplots(figsize=(10,6))
ax2 = ax1.twinx()
## 途中は省略(ひとつ目のグラフのためのデータ処理)
.to_pandas()
.plot(kind='line', color='black', ax=ax1) # このグラフのY軸の値は左軸が基準になる
## 途中は省略(二つ目のグラフのためのデータ処理)
.to_pandas()
.plot(kind='line', color='red', ax=ax2) # このグラフのY軸の値は右軸が基準になる