Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
『改訂新版前処理大全』の話と Apache Parquet の話 #TokyoR
Search
bob3bob3
June 08, 2024
Programming
0
740
『改訂新版前処理大全』の話と Apache Parquet の話 #TokyoR
『改訂新版前処理大全』のR言語版サンプルコードとApache parquetによる高速化の話。 #TokyoR
bob3bob3
June 08, 2024
Tweet
Share
More Decks by bob3bob3
See All by bob3bob3
RでPSM分析
bob3bob3
1
200
Rでコンジョイント分析 2024年版
bob3bob3
0
890
R言語の環境構築と基礎 Tokyo.R 112
bob3bob3
0
480
『データ可視化学入門』をPythonからRに翻訳した話(増強版)
bob3bob3
0
430
『データ可視化学入門』を PythonからRに翻訳した話
bob3bob3
1
510
qeMLパッケージの紹介
bob3bob3
0
1.7k
「国と音楽」 ~spotifyrを用いて~ #muana
bob3bob3
2
500
パーマーステーションのペンギンたち#3 探索的データ分析(EDA)編
bob3bob3
1
620
Redditで遊ぼう #TokyoR 106
bob3bob3
0
670
Other Decks in Programming
See All in Programming
今年のアップデートで振り返るCDKセキュリティのシフトレフト/2024-cdk-security-shift-left
tomoki10
0
190
useSyncExternalStoreを使いまくる
ssssota
6
1k
menu基盤チームによるGoogle Cloudの活用事例~Application Integration, Cloud Tasks編~
yoshifumi_ishikura
0
110
rails statsで大解剖 🔍 “B/43流” のRailsの育て方を歴史とともに振り返ります
shoheimitani
2
930
fs2-io を試してたらバグを見つけて直した話
chencmd
0
220
テスト自動化失敗から再挑戦しチームにオーナーシップを委譲した話/STAC2024 macho
ma_cho29
1
1.3k
第5回日本眼科AI学会総会_AIコンテスト_3位解法
neilsaw
0
170
Effective Signals in Angular 19+: Rules and Helpers @ngbe2024
manfredsteyer
PRO
0
130
Full stack testing :: basic to basic
up1
1
930
CSC305 Lecture 25
javiergs
PRO
0
130
KMP와 kotlinx.rpc로 서버와 클라이언트 동기화
kwakeuijin
0
130
range over funcの使い道と非同期N+1リゾルバーの夢 / about a range over func
mackee
0
110
Featured
See All Featured
Designing for humans not robots
tammielis
250
25k
A Tale of Four Properties
chriscoyier
157
23k
KATA
mclloyd
29
14k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
356
29k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
17
2.2k
Agile that works and the tools we love
rasmusluckow
328
21k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
2
290
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
656
59k
Adopting Sorbet at Scale
ufuk
73
9.1k
Reflections from 52 weeks, 52 projects
jeffersonlam
347
20k
Raft: Consensus for Rubyists
vanstee
137
6.7k
Build The Right Thing And Hit Your Dates
maggiecrowley
33
2.4k
Transcript
『改訂新版前処理大全』の話と Apache Parquet の話 Tokyo.R #113 2024/06/08 @bob3bob3
『改訂新版前処理大全』 • 2018年に発売されてデータ分析界隈で 大きな話題となった『前処理大全』のアッ プデート版。 • データサイエンスに取り組む上で欠かせ ない前処理の効率的な処理方法を網羅 的に習得できる構成。 •
サンプルデータがApache Parquet形式 で提供されているのも特徴。 • 旧版ではR、Python、SQLを用いた実装 方法を紹介していたが、改訂新版では BigQuery準拠のSQL、最新バージョンの Pandas、Rの代わりに高速なPolarsに変 更しました。
『改訂新版前処理大全』 Rの代わりに高 速なPolarsに変 更しました。
というわけで、Rで『改訂新版前処理大全』 のサンプルコードを書いています。
例1
例1)ビジネスホテルかつ宿泊人数が1名の予約履歴の抽出 reservation(200万件、11列) hotel(5千件、39列)
例1)ビジネスホテルかつ宿泊人数が1名の予約履歴の抽出 reservation(200万件、11列) hotel(5千件、39列)
例1)ビジネスホテルかつ宿泊人数が1名の予約履歴の抽出 # Not Awesome reservation |> inner_join(hotel, by = "hotel_id")
|> dplyr::filter(hotel_type == "ビジネスホテル" & people_num == 1) # Awesome reservation |> dplyr::filter(people_num == 1) |> inner_join( hotel |> dplyr::filter(hotel_type == "ビジネスホテル") |> select(hotel_id), by = "hotel_id" )
例1)ビジネスホテルかつ宿泊人数が1名の予約履歴の抽出 # Not Awesome reservation |> inner_join(hotel, by = "hotel_id")
|> dplyr::filter(hotel_type == "ビジネスホテル" & people_num == 1) reservationとhotelをすべて結合してから条件指定によってデータの抽出を行っている。 また必要な列に絞らずhotelマスターのすべての列を出力している。
例1)ビジネスホテルかつ宿泊人数が1名の予約履歴の抽出 # Awesome reservation |> dplyr::filter(people_num == 1) |> inner_join(
hotel |> dplyr::filter(hotel_type == "ビジネスホテル") |> select(hotel_id), by = "hotel_id" ) reservationとhotelそれぞれを必要な行と列に絞ってからjoinしている。
例1)ビジネスホテルかつ宿泊人数が1名の予約履歴の抽出 Awesomeなコードの方が中央値で6倍 ぐらい速い。 joinする前にそれぞれのデータをできる 限り小さくしておくこと!
Apache Parquet による前処理の高速化
Apache Parquet による前処理の高速化 • Apache Parquet はオープンソースの列指向データファイルフォーマットで、効率的 なデータの保存と検索のために設計されています。 • 複雑なデータを一括処理するための高性能な圧縮とエンコード方式を提供し、多く
のプログラミング言語と分析ツールでサポートされています。 • Rではarrowパッケージで Apache Parquet を扱うことができます。
Apache Parquet による前処理の高速化 # データフレームとして reservation_df <- read_parquet( "https://github.com/ghmagazine/awesomebook_v2/raw/main/data/reservation.parquet" )
# Arrow Table として reservation_at <- read_parquet( "https://github.com/ghmagazine/awesomebook_v2/raw/main/data/reservation.parquet", as_data_frame = FALSE ) parquet形式のデータをarrowパッケージのread_parquet()関数で読み込む。 デフォルトではデータフレームとして読み込まれるが、引数に as_data_frame = FALSE を付けるとArrow Tableとして読み込まれる。
Apache Parquet による前処理の高速化 # データフレームの処理 reservation_df |> dplyr::filter(status != "canceled")
|> summarise(reservation_cnt = n(), .by = c(hotel_id, customer_id)) # Arrow Table の処理 reservation_at |> dplyr::filter(status != "canceled") |> summarise(reservation_cnt = n(), .by = c(hotel_id, customer_id)) |> collect() #この処理が加わっただけ ホテルごと顧客ごとの予約数の集計処理。 Arrow Table も tidyverse で処理できるが、最後に collect()を実行することで結果が得られる。
Apache Parquet による前処理の高速化 中央値で約35倍の速さ! Tidyverseのすべての機能が ApacheParquetで使えるわけではない ようですが、積極的に使っていきましょ う! eitsupiさんの以前の発表やuriboさんの 資料もご参考に。
Apache Parquet の資料 @eitsupi さん @uribo さん https://eitsupi.github.io/tokyorslide/tokyor_97 https://uribo.quarto.pub/hello-r-arrow/
例2
例2)予約履歴データに対象キャンペーン情報を付与 reservation(200万件、11列) campaign(30件、3列)
例2)予約履歴データに対象キャンペーン情報を付与 reservation(200万件、11列) campaign(30件、3列)
例2)予約履歴データに対象キャンペーン情報を付与 # Not Awesome reservation |> cross_join(campaign) |> dplyr::filter(reserved_at >=
starts_at & reserved_at <= ends_at) |> select(!c(starts_at, ends_at)) # Awesome campaign_expanded <- campaign |> rowwise() |> mutate(reserve_date = list(seq(date(starts_at), date(ends_at), by="day"))) |> unnest(reserve_date) reservation |> mutate(reserve_date = date(reserved_at)) |> left_join(campaign_expanded, by = "reserve_date",relationship = "many-to-many") |> select(!reserve_date)
# Not Awesome reservation |> cross_join(campaign) |> dplyr::filter(reserved_at >= starts_at
& reserved_at <= ends_at) |> select(!c(starts_at, ends_at)) 例2)予約履歴データに対象キャンペーン情報を付与 予約履歴にキャンペーンマスターをクロス結合、その後キャンペーン期間の行のみを抽 出。最後に不要な列を削除。
# Awesome campaign_expanded <- campaign |> rowwise() |> mutate(reserve_date =
list(seq(date(starts_at), date(ends_at), by="day"))) |> unnest(reserve_date) reservation |> mutate(reserve_date = date(reserved_at)) |> left_join(campaign_expanded, by = "reserve_date",relationship = "many-to-many") |> select(!reserve_date) 例2)予約履歴データに対象キャンペーン情報を付与 キャンペーンマスターにキャンペーン期間のすべての日付の列を追加。 日付をキーに予約履歴にキャンペーンマスターを結合。
例2)予約履歴データに対象キャンペーン情報を付与 Awesomeなコードの方がおよそ6倍速い!
全編はこちらで順次公開予定 https://morimotoosamu.github.io/awesomebook_v2/
Enjoy!