Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.

クロス集計をBash(とawk)だけで実装した話

25.717 Aufrufe

Veröffentlicht am

みんな大好きシェル芸シリーズ。

元々社内用に書いていたシェルスクリプトでしたが、面白かったのでまとめました。
cut, paste, sed, awk などを駆使してTSV形式のクロス集計表加工まで行った話。

Github
https://github.com/iktakahiro/gis/tree/master/src/crosstabj_3columns

Veröffentlicht in: Technologie
  • ..............ACCESS that WEBSITE Over for All Ebooks ................ ......................................................................................................................... DOWNLOAD FULL PDF EBOOK here { https://urlzs.com/UABbn } ......................................................................................................................... Download Full EPUB Ebook here { https://urlzs.com/UABbn } .........................................................................................................................
       Antworten 
    Sind Sie sicher, dass Sie …  Ja  Nein
    Ihre Nachricht erscheint hier
  • DOWNLOAD THAT BOOKS/FILE INTO AVAILABLE FORMAT - (Unlimited) ......................................................................................................................... ......................................................................................................................... Download FULL PDF EBOOK here { http://bit.ly/2m77EgH } ......................................................................................................................... .............. Browse by Genre Available eBooks ......................................................................................................................... accessibility Books Library allowing access to top content, including thousands of title from favorite author, plus the ability to read or download a huge selection of books for your pc or smartphone within minutes Christian, Classics, Comics, Contemporary, Cookbooks, Art, Biography, Business, Chick Lit, Children's, Manga, Memoir, Music, Science, Science Fiction, Self Help, History, Horror, Humor And Comedy, Suspense, Spirituality, Sports, Thriller, Travel, Young Adult, Crime, Ebooks, Fantasy, Fiction, Graphic Novels, Historical Fiction, Mystery, Non Fiction, Paranormal, Philosophy, Poetry, Psychology, Religion, Romance,
       Antworten 
    Sind Sie sicher, dass Sie …  Ja  Nein
    Ihre Nachricht erscheint hier
  • ..............ACCESS that WEBSITE Over for All Ebooks ................ ......................................................................................................................... DOWNLOAD FULL PDF EBOOK here { https://urlzs.com/UABbn } ......................................................................................................................... Download Full EPUB Ebook here { https://urlzs.com/UABbn } .........................................................................................................................
       Antworten 
    Sind Sie sicher, dass Sie …  Ja  Nein
    Ihre Nachricht erscheint hier
  • accessibility Books Library allowing access to top content, including thousands of title from favorite author, plus the ability to read or download a huge selection of books for your pc or smartphone within minutes.........ACCESS WEBSITE Over for All Ebooks ..... (Unlimited) ......................................................................................................................... Download FULL PDF EBOOK here { https://urlzs.com/UABbn } .........................................................................................................................
       Antworten 
    Sind Sie sicher, dass Sie …  Ja  Nein
    Ihre Nachricht erscheint hier
  • DOWNLOAD THAT BOOKS/FILE INTO AVAILABLE FORMAT - (Unlimited) ......................................................................................................................... ......................................................................................................................... Download FULL PDF EBOOK here { http://bit.ly/2m77EgH } ......................................................................................................................... .............. Browse by Genre Available eBooks ......................................................................................................................... accessibility Books Library allowing access to top content, including thousands of title from favorite author, plus the ability to read or download a huge selection of books for your pc or smartphone within minutes Christian, Classics, Comics, Contemporary, Cookbooks, Art, Biography, Business, Chick Lit, Children's, Manga, Memoir, Music, Science, Science Fiction, Self Help, History, Horror, Humor And Comedy, Suspense, Spirituality, Sports, Thriller, Travel, Young Adult, Crime, Ebooks, Fantasy, Fiction, Graphic Novels, Historical Fiction, Mystery, Non Fiction, Paranormal, Philosophy, Poetry, Psychology, Religion, Romance,
       Antworten 
    Sind Sie sicher, dass Sie …  Ja  Nein
    Ihre Nachricht erscheint hier

クロス集計をBash(とawk)だけで実装した話

  1. 1. クロス集計をbash(とawk)だけで実装した話 ~ bash最強伝説 : 序 ~ 2012-12-02 @iktakahiro
  2. 2. 自己紹介@iktakahiro株式会社ALBERT システム開発部レコメンドエンジンとか作ってるよ! 最近気になっていること: 破とQの間に伊吹マヤに何が起こったのか。
  3. 3. このスライドに書いてあることそれなりのデータ量(※1)のログファイルをbashスクリプトでクロス集計表にするまで行ったというお話。 ※1 数GBとか、数千万行とか。それ以上は試してない。
  4. 4. クロス集計とは?ピボットテーブルと言うやつです。性別 血液型 A型 B型 O型 AB型男子 A型女子 A型男子 O型 男子 1 0 1 1女子 B型男子 AB型 女子 2 1 0 0女子 A型
  5. 5. カウントのパターンもあれば、合算のパターンもある(今回はこっち)。ユーザー 商品 金額Aさん アイス 130Aさん アイス 180Bさん ジュース 120 アイス ジュース OREOBさん アイス 130Iさん OREO 210 Aさん 310 0 0Iさん OREO 210Iさん OREO 210 Bさん 130 120 0 Iさん 0 0 630
  6. 6. カジュアルなクロス集計の選択肢Excel => 乙。Rでやれば良いじゃない=> ちょっと前まではやってたけど、メモリ 馬鹿食い&積んでも別の制約にひっかかかるCとかJAVAでry=>
  7. 7. bashでやろう。
  8. 8. なぜbashか? Linux/Unix あればおk cutでカラム抽出簡単 catで縦マージpasteで横マージ sort超速い <= Point1 実はJOINできる <= Point2 S・E・D ! S・E・D !※ さすがに一部の処理はしんどいのでawkでフォロー
  9. 9. テキストファイル処理との親和性が半端じゃないです。TSVファイルのカラム入れ換えとか抽出とか、正規表現置換とかで苦労している人はいますぐ覚えましょう。どんなに巨大なファイルでもheadとtailで中身覗ける。(今回は登場しないけど)シェルスクリプトのTips的な要素もあり。
  10. 10. 処理の流れ1) 必要なカラムを抽出2) クロス集計の行と列の要素を取り出す3) awkでファイル分割する4) awkで集計する(sum + group by)5) sort でソート6) 2)で取り出した行の要素と 5)の結果をJOIN7) paste と cat でマージしてリストを表に加工
  11. 11. 1)必要なカラムを抽出ユーザー 商品 金額 月Aさん アイス 130 12月 [月] の列は要らない。Aさん アイス 180 11月Bさん ジュース 120 11月Bさん アイス 130 12月 必要なものだけ抽出されていればこの処理は不Iさん OREO 210 11月 要だけど、データ量が多いとそれもしんどいのIさん OREO 210 10月 で一番差最初にやる。Iさん OREO 210 2月 抽出するのは以降の処理対象のデータを減らし たいというのが理由。
  12. 12. # 1, 2, 3 カラム目を抽出したいので cat hoge.txt ¦awk {print $1, $2, $3} > tmp_data.txtユーザー 商品 金額 月Aさん アイス 130 12月Aさん アイス 180 11月 ユーザー 商品 金額Bさん ジュース 120 11月 Aさん アイス 130Bさん アイス 130 12月 Aさん アイス 180Iさん OREO 210 11月 Bさん ジュース 120Iさん OREO 210 10月 Bさん アイス 130Iさん OREO 210 2月 Iさん OREO 210 Iさん OREO 210 Iさん OREO 210
  13. 13. 2)クロス集計の行と列の要素を取り出す # クロス集計表の行になる部分を抽出してユニーク化&ソート cut -f 1 -d , tmp_data.txt ¦sort -u > rowname.txtユーザー 商品 金額Aさん アイス 130 ユーザーAさん アイス 180 AさんBさん ジュース 120 BさんBさん アイス 130 IさんIさん OREO 210Iさん OREO 210 MySQLとかの感覚だとこの処理は遅そうですがIさん OREO 210 速いです。
  14. 14. # クロス集計表の列になる部分を抽出してユニーク化&ソート cut -f 2 -d , tmp_data.txt ¦sort -u > tmp_header.txt # 改行をタブに変えて縦横変換 tr n t < tmp_header.txt > header.txtユーザー 商品 金額 商品Aさん アイス 130 アイスAさん アイス 180 ジュースBさん ジュース 120 OREOBさん アイス 130Iさん OREO 210Iさん OREO 210 商品 アイス ジュース OREOIさん OREO 210 MySQLとかの感覚だとこの処理は遅そうですが 速いです。(二回目
  15. 15. 3)awkでファイル分割する # tmp_data.txt を 2列目の中身でファイル分割 awk -F, {print > "split_"$2} tmp_data.txt ユーザー 商品 金額 Aさん アイス 130 Aさん アイス 180ユーザー 商品 金額 Bさん アイス 130Aさん アイス 130Aさん アイス 180 ユーザー 商品 金額Bさん ジュース 120 Bさん ジュース 120Bさん アイス 130 ユーザー 商品 金額Iさん OREO 210 Iさん OREO 210Iさん OREO 210 Iさん OREO 210Iさん OREO 210 Iさん OREO 210
  16. 16. 4)awkで集計する, 5) sortでソートする # tmp_data.txt を 2列目の中身でファイル分割 awk -F, {a[$1]+=$3;}END{for(i in a)print i","a[i];} split_${file} ¦ sort -t 1 > sort_${file}ユーザー 商品 金額 アイス買った人 合計金額Aさん アイス 130 Aさん 310Aさん アイス 180 Bさん 130Bさん アイス 130 ジュース買った人 合計金額 Bさん 120ユーザー 商品 金額Bさん ジュース 120 豚 合計金額 Iさん 630ユーザー 商品 金額Iさん OREO 210 このawkの処理は色々使えるので覚えてね!Iさん OREO 210 集計結果をパイプで渡してsortをかけてるよ。Iさん OREO 210
  17. 17. 6) 2)で取り出した行の要素と 5)の結果をJOIN... 前に一応今回のポイントなので解説。クロス集計表の作成がなぜめんどくさいか? => レコードがないものを 0 で埋めなければいけないから。 アイス ジュース OREO [ Aさん x OREO ] とかAさん 310 0 0 [ Iさん x アイス] とかがそう。Bさん 130 120 0Iさん 0 0 630
  18. 18. 0 で埋めないと(nullでもいいけど)マージがうまくいかなくて 残念なことになっちゃう。アイス買った人 合計金額 Aさん 310 Bさん 130ジュース買った人 合計金額 それぞれ行の数がばらばら。分割したファイルに Bさん 120 漏れなく要素が存在するわけではない。 豚 合計金額 Iさん 630 ??? ユーザー アイス ジュース OREO Aさん 310 120 630 Bさん 130
  19. 19. で、join コマンドです。
  20. 20. # 2)で取り出した行の要素と 5)の結果をJOIN からの∼ S・E・D !join -t , -1 1 -2 1 -a 1 rowname.txt sort_${file} ¦ awk -F, {print $2} ¦ sed s/^$/0/g >split_sum_${file} ユーザー アイス買った人 合計金額 ! Aさん Aさん 310 IN Bさん 130 JO Bさん Iさん 0 Iさん ジュース買った人 合計金額アイス買った人 合計金額 Aさん 0 Aさん 310 Bさん 120 Bさん 130 Excellent! Iさん 0ジュース買った人 合計金額 OREO買った人 合計金額 Bさん 120 Aさん 0 Bさん 0 豚 合計金額 Iさん 630 Iさん 630
  21. 21. # JOIN の解説join -t , -1 1 -2 1 -a 1 rowname.txt sort_${file}join コマンドは、デフォルトでは join 可能だった行のみを出力する。ただし、-a オプションをつけると、「不一致でjoinできなかったキー」も含めて出力してくれる。 Aさん JOIN ! Bさん Bさん 120 Iさん Aさん 0 Bさん 120 120 Iさん 0# この結果の2列目を awk で抽出し、空行に sed で 0 を挿入している。awk -F, {print $2} ¦ sed s/^$/0/g > split_sum_${file}
  22. 22. 7)paste で マージしてリストを表に加工# 見出しとなる行、列と、分割処理した集計結果をマージcp header.txt sum_result.txtpaste rowname.txt split_sum_* >> sum_result.txt 商品 アイス ジュース OREO ユーザー Aさん 310 0 0 Bさん 130 120 0 Iさん 0 0 630
  23. 23. できあがり! アイス ジュース OREO Aさん 310 0 0 Bさん 130 120 0 Iさん 0 0 630 ※ できあがるのはTSVファイル。
  24. 24. ベンチマーク 仮想環境上のCentOSでやったので レコード 2,500万 I/Oはかなり遅いです。ファイルサイズ 800MB DBで2,500万インサートとかそれだけで 死ねる。 クロス結果行 300万 クロス結果列 30 メモリ 16GB Githubでスクリプトを公開するので 処理時間 5分 みんなでベンチマークしてね!
  25. 25. 補足ファイル分割しているので、集計処理を並列化することもできる。並列実行は & とか xargs とかを使うと良いよ!あまり大きい固まりをawkに投げると帰ってこなくなるしね。joinするには 対象のファイル(のキー)がソート済みである必要があります。joinには一致しなかった行だけを出力する -v オプションも。bashでsortする場合は問答無用で export LC_ALL=C しる!手元では事故ったことないけどソート周りに罠がありそう。
  26. 26. まとめ bash最強!! AAAヴンダーってなんかもう
  27. 27. おわり。

×