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']))
集計列追加
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))
行を list[dict] で取り出す
for row in df.iter_rows(named=True)
pandas と違い index は渡ってこない、named=True で辞書としてアクセスできる(ない場合は tuple)
df「
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 内のグループで連番を振る
ソート
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()
pl.read_parquet などのメソッドで gs:// の URL など引き続き使える
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