Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Polars と遅延評価

Yoshitaka Tomiyama
October 24, 2023
1.6k

Polars と遅延評価

Polars の遅延評価機能「Lazy API」について、現時点でわかっていることをまとめてみました。

Lazy API をざっくり評価する Colab. も同時に公開しています。
https://colab.research.google.com/drive/1-fM87oYsi_Ea6ivTDYCkKlmWQ7oF2wQy?usp=sharing

Yoshitaka Tomiyama

October 24, 2023
Tweet

Transcript

  1. 弁財天参加者募集!
 ❖ AI ミュージックバトル!『弁財天〜第二幕〜』 
 ❖ 伴奏に AI でメロディを乗せる! 


    ❖ 皆で聴いて良い方に投票! 
 ❖ バトル型トーナメント!! 
 ❖ 10/28 土 (来週!!!)
 benzaiten-online.com で
 予選投票中!!!!!!!

  2. Polars は何故速い?
 ❖ バックエンドが Rust で書かれている
 ➢ Polars の rs

    は Rust
 ❖ マルチコアでの並列処理を可能な限り利用する
 ➢ Embarrasingly parallel
 ❖ 遅延評価を提供する API、クエリ最適化
 https://www.pola.rs/posts/i-wrote-one-of-the-fastest-dataframe-libraries/
  3. Polars は何故速い?
 ❖ バックエンドが Rust で書かれている
 ➢ Polars の rs

    は Rust
 ❖ マルチコアでの並列処理を可能な限り利用する
 ➢ Embarrasingly parallel
 ❖ 遅延評価を提供する API、クエリ最適化
 https://www.pola.rs/posts/i-wrote-one-of-the-fastest-dataframe-libraries/ 今日はこれについて話します!

  4. Python における遅延評価
 短絡評価(short-circuit evaluation)・・遅延評価の一種
 ❖ and での評価なので片方が False なら式全体が False

    →もう片方は評価されない 
 ➢ こう書くことで idx に out of range な値が来ても右辺で IndexError にならない
  5. Polars における遅延評価
 ❖ クソデカ CSV に対して
 ➢ データフレームとして読み込む 
 ➢

    先頭の N 行を取得する(もしくは 先頭の N 行を用いて値を計算する) 
 Polars でも同じようなことができる

  6. Polars における遅延評価
 ❖ クソデカ CSV に対して
 ➢ データフレームとして読み込む 
 ➢

    先頭の N 行を取得する(もしくは 先頭の N 行を用いて値を計算する) 
 Polars でも同じようなことができる
 正格評価:Eager API
 693ms
 遅延評価:Lazy API
 33ms

  7. 遅延評価機能 Lazy API の使い方
 いつもの df に対し df.lazy() とするだけで LazyFrame

    クラスになってくれる
 ❖ 最初から LazyFrame で読み込むことも可(この時点でデータは読まれない)

  8. 遅延評価機能 Lazy API の使い方
 ➢ 一部 pandas-like な書き方をサポートしていないがち( df["col"] みたいな列抽出とか)

    
 ▪ pivot もできない(代替手段はある) 
 LazyFrame は DataFrame と「基本的」に同様に操作できる

  9. 遅延評価機能 Lazy API の使い方
 ➢ 蓄積されたクエリはいい感じに最適化される 
 ▪ filter や

    select は最初にやる、みたいなシンプルなものから最適な型への変換や結合順序 の推定までさまざま。詳しくは Polars book へ
 一連の操作(エクスプレッション)はクエリとして蓄積されていく

  10. 遅延評価機能 Lazy API の使い方
 ➢ 蓄積されたクエリはいい感じに最適化される 
 ▪ filter や

    select は最初にやる、みたいなシンプルなものから最適な型への変換や結合順序 の推定までさまざま。詳しくは Polars book へ
 一連の操作(エクスプレッション)はクエリとして蓄積されていく
 正格評価:Eager API
 1.06s(処理完了)
 遅延評価:Lazy API
 391μs(クエリ蓄積のみ)

  11. 遅延評価機能 Lazy API の使い方
 ➢ こうすることでようやく中身が見えるので、 EDA や初期構築時など中身を頻繁に確認したい場面に は向かないかも
 lf.collect()

    とすることで式が評価され、データフレームが具体化
 LazyFrame を表示すると
 蓄積されたクエリが見える 
 LazyFrame.collect()
 で具体化

  12. Streaming API
 ❖ Lazy API の機能の一つ(開発中だけど使える)
 ❖ collect の引数に streaming=True

    を渡すだけ
 ❖ クエリ最適化の結果「結局使うデータ」のみを処理する。爆速
 ❖ すべての操作でサポートされているわけでない
 ➢ Eager API、Lazy API、Streaming API における「この記述はできるけど、これはできない」みたい なやつはチョットわからない(アップデートでどんどん変わりそう) 

  13. Lazy API が嬉しいケース
 ❖ Lazy API を使うことで顕著にパフォーマンス向上が見込めるケースについて johannyjm1 が確認しているのは以下
 ➢

    ① Streaming API を利用している、かつ具体化されるデータ件数が元データより減っている場合 
 ➢ ②相当“無駄のある”クエリを書いちゃっているとき 
 ▪ しかし、一連の記述においては気づかないがち 
 ①クソデカ CSV 読 み込み
 ↓
 先頭 100 行取得 
 
 Eager API: 693ms
 Lazy API: 33ms
 ②無駄クエリ
 
 
 Eager API: 2.89s
 Lazy API: 445ms

  14. Lazy API が嬉しいケース
 ❖ というか Eager API も裏で普通に Lazy API

    を呼んでいる
 ❖ 余計なことしなくても全部 Eager API で良い日は来るかもしれない
 それ以外はまちまち... Eager API も普通に速い

  15. まとめ
 ❖ Polars はさまざまな理由で高速だが、今回は遅延評価に注目した
 ➢ 遅延評価とは Python を普段書いてると意識しにくいが、案外身近な便利評価戦略である 
 ❖

    Polars の遅延評価機能は Lazy API として非常にシンプルに導入できる
 ➢ Lazy API の性能はそこそこだが、使ってるときっと良いことがある 
 ❖ 弁財天をお楽しみに!!!!!!!!!!!!!!!