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
1.3k
『改訂新版前処理大全』の話と Apache Parquet の話 #TokyoR
『改訂新版前処理大全』のR言語版サンプルコードとApache parquetによる高速化の話。 #TokyoR
bob3bob3
June 08, 2024
Tweet
Share
More Decks by bob3bob3
See All by bob3bob3
RとLLMで自然言語処理
bob3bob3
3
790
RでPSM分析
bob3bob3
1
400
Rでコンジョイント分析 2024年版
bob3bob3
0
2.1k
R言語の環境構築と基礎 Tokyo.R 112
bob3bob3
0
620
『データ可視化学入門』をPythonからRに翻訳した話(増強版)
bob3bob3
0
560
『データ可視化学入門』を PythonからRに翻訳した話
bob3bob3
1
620
qeMLパッケージの紹介
bob3bob3
0
2.3k
「国と音楽」 ~spotifyrを用いて~ #muana
bob3bob3
2
620
パーマーステーションのペンギンたち#3 探索的データ分析(EDA)編
bob3bob3
1
800
Other Decks in Programming
See All in Programming
Grafana:建立系統全知視角的捷徑
blueswen
0
320
Pythonではじめるオープンデータ分析〜書籍の紹介と書籍で紹介しきれなかった事例の紹介〜
welliving
3
860
高速開発のためのコード整理術
sutetotanuki
1
370
例外処理とどう使い分ける?Result型を使ったエラー設計 #burikaigi
kajitack
16
5.9k
humanlayerのブログから学ぶ、良いCLAUDE.mdの書き方
tsukamoto1783
0
170
フルサイクルエンジニアリングをAI Agentで全自動化したい 〜構想と現在地〜
kamina_zzz
0
400
SourceGeneratorのススメ
htkym
0
180
Python札幌 LT資料
t3tra
7
1.1k
AgentCoreとHuman in the Loop
har1101
5
210
コマンドとリード間の連携に対する脅威分析フレームワーク
pandayumi
1
440
TerraformとStrands AgentsでAmazon Bedrock AgentCoreのSSO認証付きエージェントを量産しよう!
neruneruo
4
2.7k
16年目のピクシブ百科事典を支える最新の技術基盤 / The Modern Tech Stack Powering Pixiv Encyclopedia in its 16th Year
ahuglajbclajep
5
970
Featured
See All Featured
Ecommerce SEO: The Keys for Success Now & Beyond - #SERPConf2024
aleyda
1
1.8k
Raft: Consensus for Rubyists
vanstee
141
7.3k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
34
2.6k
Rails Girls Zürich Keynote
gr2m
96
14k
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
1
1.3k
Stop Working from a Prison Cell
hatefulcrawdad
273
21k
Tips & Tricks on How to Get Your First Job In Tech
honzajavorek
0
420
Code Reviewing Like a Champion
maltzj
527
40k
The Illustrated Guide to Node.js - THAT Conference 2024
reverentgeek
0
250
AI Search: Implications for SEO and How to Move Forward - #ShenzhenSEOConference
aleyda
1
1.1k
Joys of Absence: A Defence of Solitary Play
codingconduct
1
280
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
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!