Polars
関数に pl.col('name') を渡せる
df_hoge[df_hoge['a'] < 10] のように、DataFrame 名を繰り返さなくていいのが助かる
DataFrame の変数名を説明的にすると入力がダルくなる問題がなくなる
pl.col(r"^...$") で正規表現で列を選択、^ ~ $ である必要がある(任意の正規表現をかけるわけではない)
色々なメソッドが _ 区切りに寄せられた
.to_list や .n_unique、.fill_null など
df.glimpse() で 列ベースで見る
df.mean() などは列方向、df.mean_horizontal() は行方向
列選択
df.select(['col1', 'col2'])
df.select(pl.exclude('foo')) 除外選択便利
import polars.selectors as cs で、セレクタを色々結合できる、あんま使わなそう
df.select(pl.col('foo').name.prefix('col_')) で別名をつけつつ選択
行選択・しぼりこみ
df.filter(pl.col('foo') < 10)
df.filter(pl.col('foo').is_in(['a', 'b', 'c']))
1行だけ選択
df.row(by_predicate=(pl.col("ham") == "b"), named=True)
0 行でも 2 行以上でも RowsError の派生エラーが raise する
集計列追加
df.with_columns(new_col=pl.col('foo') + 1) 名前付き引数のほうが好みかな
df.with_columns((pl.col('foo') + 1).alias('new_col'))
df.with_columns(embedding=pl.Series(embs))
apply 相当の処理もこの流れでやる
df.with_columns(applied=pl.col('foo').map_elements(my_func, return_dtype=pl.String))
行を list[dict] で取り出す
for row in df.iter_rows(named=True)
pandas と違い index は渡ってこない、named=True で辞書としてアクセスできる(ない場合は tuple)
df.to_dicts() 複数形でよぶと records 形式
pandas での df.to_dict(orient='records')
グループごとの処理
df.iter_slices(n_rows=5000) 5000 行ごとの DataFrame で繰り返す
df.with_column(index=pl.arange(1, pl.len() + 1).over('group_id')
group_id 内のグループで連番を振る
df.partition_by('col') で col 列の値ごとにグループ化された DataFrame が iterate される
df[['category', 'score']].group_by('category').agg([pl.mean('score'), pl.count()])
ソート
pl.col('foo', 'bar').sort_by('foo')
descending=True で降順
nulls_last=True 欠損を末尾へ
df.sort([pl.col("a"), pl.col("b")],descending=[False, True])
条件分岐しつつ取得
df.select(pl.when(pl.col('foo') == 1)).then(...).otherwise(...)
pivot /unpivot
pl.col('text').str.len_chars()
Cloud Storage
pl.read_parquet などのメソッドで gs:// の URL など引き続き使える
一方書き込みはそのままできない
df.write_parquet("gs://...", use_pyarrow=True) ならできる
素は Rust 実装だからで、use_pyarrow だと Python の世界でパスが解釈されて gcsfs やらが働く感じか
BigQuery からテーブルに
...でいいかと思いきや、Series or DataFrame が返るので、cast か assert する
code:to_arrow.py
res = client.query(query)
df = pl.from_arrow(res.result().to_arrow())
# return cast(pl.DataFrame, df)
assert type(df) == pl.DataFrame
return df