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

PyData.Fukuoka#6_LT_slide

B22a79a9c1bf42c1825ce42dedd41765?s=47 shinpsan
November 22, 2019

 PyData.Fukuoka#6_LT_slide

前処理するとき便利だからよく
pandas.DataFrame.apply(lambda)
使っちゃうけど遅いから本当は
pandas.Series.map()
使った方がいいと思う

B22a79a9c1bf42c1825ce42dedd41765?s=128

shinpsan

November 22, 2019
Tweet

Transcript

  1. 前処理するとき便利だからよく
 pandas.DataFrame.apply(lambda)
 使っちゃうけど遅いから本当は
 pandas.Series.map()
 使った方がいいと思う
 PyData.Fukuoka #6
 LT
 @shinpsan


  2. 自己紹介
 下積みの父@shinpsan
 小売業のデータサイエンティスト(12月まで。年明け転職します)
 MENSA会員
 合同会社ocojoで副業
 
 twitter : 
 仕事

    : 
 特技:
 趣味: 
 

  3. 話すこと
 タイトルに書いたことが全てです。
 pandasの基本的なところなのでみんな知ってる内容かも。
 
 知ってる方はヒマだと思うので、心の中で
 「シカ」って10回言った後、
 「サンタクロースが乗っているのは?」に答えてて下さい


  4. 背景
 クソみたいなデータ渡されたと文句言いながら、
 いつもクソみたいなコード書いてることを反省。
 


  5. 再現データ
 ラベル 営業時間 値1 値2 値3 • 1ファイルにつき何個か値が格納された ファイルが大量にある •

    それを集めてきて1つのテーブルにした もの • ラベルが元のファイル名
  6. やりたいこと(持っていきたい方向)
 店舗の営業時間体系ごとの
 • 三角おにぎり
 • パックおにぎり
 • 寿司
 のラベルをつけて集計とか
 可視化とかいろいろ


  7. 再現データ
 
 ラベル 営業時間 値1 値2 値3 • おにぎり、寿司、パックおにぎり 判別はラベルの文字列から可能

    • 営業時間は9~21時 or 24時間営業
  8. クソみたいなところ①
 ラベル 営業時間 値1 値2 値3 ラベルの文字列の長さがバラバラ

  9. クソみたいなところ②
 ラベル 営業時間 値1 値2 値3 おにぎり、寿司の判別は文字列の先頭 パックおにぎりの判別は文字列の最後

  10. クソみたいなところ③
 ラベル 営業時間 値1 値2 値3 ラベルに区切り文字とか入って無い

  11. 手順1
 ラベル 営業時間 値1 値2 値3 ラベル列の各行に関して、 先頭7文字が”ONIGIRI” かどうか、 先頭5文字が”SUSHI”

    かどうか、 最後4文字が”pack” かどうか 判別
  12. 手順2
 ラベル 営業時間 値1 値2 値3 営業時間列の各行に関して、 “9-21” or “24h”

    判別
  13. 手順3
 ラベル 営業時間 値1 値2 値3 手順1,2の判別を元に 新たなラベル列作成 新ラベル おにぎり_9-21

    おにぎり_24h ・ ・ ・
  14. ここで本題
 どんな処理書く?
 • for + iterrows()
 • df.apply()
 • Series.map()


  15. ①for i, row in {pd.DataFrame}.iterrow():
 ラベル 営業時間 値1 値2 値3

    データフレームの1行1行に対して ループ処理 処理 ↓ 処理 ↓ 処理 ↓ 処理 ↓ 処理 ↓
  16. ①for i, row in {pd.DataFrame}.iterrow():


  17. ②{pd.DataFrame}.apply(lambda x: {})
 ラベル 営業時間 値1 値2 値3 データフレームの各行に対して 同じ処理を一括適応

    lambda x のxには各行が1行のDFにみたいにして渡される x[“ラベル”]みたいにして使うとこ選べる ✖ 処理 ✖ 処理 ✖ 処理 ✖ 処理 ✖ 処理
  18. ②{pd.DataFrame}.apply(lambda x: {})


  19. ③{pd.Series}.map(lambda x: {})
 ラベル ✖ 処理 ✖ 処理 ✖ 処理

    ✖ 処理 ✖ 処理 Seriesの各要素に対して 同じ処理を一括適応
  20. ③{pd.Series}.map(lambda x: {})


  21. None
  22. 実行速度比較 1万行まで
 iterrowsだと1万行のデータで 1~2秒かかる データの行数 処理にかかった時間

  23. 実行速度比較 10万行まで
 df.apply()だと10万行のデータで ~2秒かかる

  24. 実行速度比較 1000万行まで
 Series.map()だと1000万行のデータで 約5秒かかる

  25. まとめ
 ただの肌感ですが、jupyterで分析してて、
 そこまで気にならない待ち時間は2秒くらい
 • for + iterrows 1万行
 • df.apply

    10万行
 • Series.map 400万行
 まぁ、結論としてループは使わない。
 df.apply()は何も考えずに記述できるけど遅いから、
 Series.map()でやる方がいいですね。

  26. enjoy!
 答え:そり(トナカイには乗っていない)