Slide 1

Slide 1 text

メソッドチェーンを使って DataFrameの可読性と保守性を 向上させよう みんなのPython勉強会#106 2024/07/18

Slide 2

Slide 2 text

自己紹介 NTT コミュニケーションズ株式会社に2019年新卒入社 WebRTCプラットフォーム SkyWayでWebRTCエンジニア 副業 DataScientist@出版系 / MLOps@医療系 趣味はラーメン 🍜とコーヒー ☕️ WebRTCエンジニア / DataScientist 内田 裕貴 x: @yuki_wtz

Slide 3

Slide 3 text

話したいこと1 こういうコード良く書きますよね?

Slide 4

Slide 4 text

話したいこと1 こういうコード良く書きますよね? df = pd.read_csv("hoge.csv") df = df[df["userId"] == 1] df["GB"] = df["MB"] * 1000 df["TB"] = df["GB"] * 1000 df = df.drop("MB") df = df.drop("GB")

Slide 5

Slide 5 text

話したいこと1 dfという変数に対してひたすら操作 を加えていく こういうコード良く書きますよね? df = pd.read_csv("hoge.csv") df = df[df["userId"] == 1] df["GB"] = df["MB"] * 1000 df["TB"] = df["GB"] * 1000 df = df.drop("MB") df = df.drop("GB")

Slide 6

Slide 6 text

話したいこと1 この書き方の好ましくない点1 df = pd.read_csv("hoge.csv") df = df[df["userId"] == 1] df["GB"] = df["MB"] * 1000 df["TB"] = df["GB"] * 1000 df = df.drop("MB") df = df.drop("GB")

Slide 7

Slide 7 text

話したいこと1 この書き方の好ましくない点1 df = pd.read_csv("hoge.csv") df = df[df["userId"] == 1] df["GB"] = df["MB"] * 1000 df["TB"] = df["GB"] * 1000 df = df.drop("MB") df = df.drop("GB") 「dfという変数、今どうなってる?」

Slide 8

Slide 8 text

話したいこと1 この書き方の好ましくない点1 df = pd.read_csv("hoge.csv") df = df[df["userId"] == 1] df["GB"] = df["MB"] * 1000 df["TB"] = df["GB"] * 1000 df = df.drop("MB") df = df.drop("GB") 「dfという変数、今どうなってる?」 jupyter notebookなどの場合、複数セルにわ たって同じ変数を操作することが多い

Slide 9

Slide 9 text

話したいこと1 この書き方の好ましくない点1 df = pd.read_csv("hoge.csv") df = df[df["userId"] == 1] df["GB"] = df["MB"] * 1000 df["TB"] = df["GB"] * 1000 df = df.drop("MB") df = df.drop("GB") 「dfという変数、今どうなってる?」 jupyter notebookなどの場合、複数セルにわ たって同じ変数を操作することが多い 処理に順序性がある(この処理を実行していな いと後続の処理がバグる)場合、とりあえず最 初のセルから再実行する・・・

Slide 10

Slide 10 text

話したいこと1 この書き方の好ましくない点1 df = pd.read_csv("hoge.csv") df = df[df["userId"] == 1] df["GB"] = df["MB"] * 1000 df["TB"] = df["GB"] * 1000 df = df.drop("MB") df = df.drop("GB") 「dfという変数、今どうなってる?」 jupyter notebookなどの場合、複数セルにわ たって同じ変数を操作することが多い 処理に順序性がある(この処理を実行していな いと後続の処理がバグる)場合、とりあえず最 初のセルから再実行する・・・ ごちゃごちゃ操作していくうちに、最初のセ ルから実行しても動かなくなったりする

Slide 11

Slide 11 text

話したいこと1 この書き方の好ましくない点2 df = pd.read_csv("hoge.csv") df_1 = df[df["pattern"] == 1] df_1["GB"] = df_1["MB"] * 1000 df_1["TB"] = df_1["GB"] * 1000 df_1_1 = df_1.drop("MB") df_1_2 = df_1_1.drop("GB")

Slide 12

Slide 12 text

話したいこと1 この書き方の好ましくない点2 df = pd.read_csv("hoge.csv") df_1 = df[df["pattern"] == 1] df_1["GB"] = df_1["MB"] * 1000 df_1["TB"] = df_1["GB"] * 1000 df_1_1 = df_1.drop("MB") df_1_2 = df_1_1.drop("GB") DataFrameを作りまくってメモリを圧迫

Slide 13

Slide 13 text

話したいこと1 この書き方の好ましくない点2 df = pd.read_csv("hoge.csv") df_1 = df[df["userId"] == 1].copy() df_1["GB"] = df_1["MB"] * 1000 df_1["TB"] = df_1["GB"] * 1000 df_1_1 = df_1.drop("MB") df_1_2 = df_1_1.drop("GB") DataFrameを作りまくってメモリを圧迫

Slide 14

Slide 14 text

話したいこと1 この書き方の好ましくない点2 df = pd.read_csv("hoge.csv") df_1 = df[df["userId"] == 1].copy() df_1["GB"] = df_1["MB"] * 1000 df_1["TB"] = df_1["GB"] * 1000 df_1_1 = df_1.drop("MB") df_1_2 = df_1_1.drop("GB") DataFrameを作りまくってメモリを圧迫 軽量のデータであれば問題ないが、GB級のデ ータを扱うようになると、この無駄なメモリ 使用に苦しむことになる

Slide 15

Slide 15 text

話したいこと2 メソッドチェーンを使ってみよう df = pd.read_csv("hoge.csv") df_1 = df[df["pattern"] == 1] df_1["GB"] = df_1["MB"] * 1000 df_1["TB"] = df_1["GB"] * 1000 df_1_1 = df_1.drop("MB") df_1_2 = df_1_1.drop("GB")

Slide 16

Slide 16 text

話したいこと2 メソッドチェーンを使ってみよう df = ( pd.read_csv("hoge.csv") .query("pattern == 1") .assign(GB=lambda x: x["MB"] * 1000) .assign(TB=lambda x: x["GB"] * 1000) .drop(columns=["MB", "GB"]) ) df = pd.read_csv("hoge.csv") df = df[df["userId"] == 1] df["GB"] = df["MB"] * 1000 df["TB"] = df["GB"] * 1000 df = df.drop("MB") df = df.drop("GB")

Slide 17

Slide 17 text

話したいこと2 メソッドチェーンを使ってみよう df = ( pd.read_csv("hoge.csv") .query("userId == 1") .assign(GB=lambda x: x["MB"] * 1000) .assign(TB=lambda x: x["GB"] * 1000) .drop(columns=["MB", "GB"]) ) df = pd.read_csv("hoge.csv") df = df[df["userId"] == 1] df["GB"] = df["MB"] * 1000 df["TB"] = df["GB"] * 1000 df = df.drop("MB") df = df.drop("GB")

Slide 18

Slide 18 text

話したいこと2 メソッドチェーンの利点 df = ( pd.read_csv("hoge.csv") .query("userId == 1") .assign(GB=lambda x: x["MB"] * 1000) .assign(TB=lambda x: x["GB"] * 1000) .drop(columns=["MB", "GB"]) )

Slide 19

Slide 19 text

話したいこと2 メソッドチェーンの利点 df = ( pd.read_csv("hoge.csv") .query("userId == 1") .assign(GB=lambda x: x["MB"] * 1000) .assign(TB=lambda x: x["GB"] * 1000) .drop(columns=["MB", "GB"]) ) dfという変数の状態を考える必 要がなくなる

Slide 20

Slide 20 text

話したいこと2 メソッドチェーンの利点 df = ( pd.read_csv("hoge.csv") .query("userId == 1") .assign(GB=lambda x: x["MB"] * 1000) .assign(TB=lambda x: x["GB"] * 1000) .drop(columns=["MB", "GB"]) ) dfという変数の状態を考える必 要がなくなる プログラミング全般に言えるが、 変化する値は少ければ少ないほど バグが起きづらい

Slide 21

Slide 21 text

話したいこと2 メソッドチェーンの利点 df = ( pd.read_csv("hoge.csv") .query("userId == 1") .assign(GB=lambda x: x["MB"] * 1000) .assign(TB=lambda x: x["GB"] * 1000) .drop(columns=["MB", "GB"]) ) dfという変数の状態を考える必 要がなくなる dfに関わる操作が一塊になり、 変更が容易になる

Slide 22

Slide 22 text

話したいこと2 メソッドチェーンの利点 df = ( pd.read_csv("hoge.csv") .query("userId == 1") .assign(GB=lambda x: x["MB"] * 1000) .assign(TB=lambda x: x["GB"] * 1000) .drop(columns=["MB", "GB"]) ) dfという変数の状態を考える必 要がなくなる dfに関わる操作が一塊になり、 変更が容易になる 無駄なdataframeが作られない

Slide 23

Slide 23 text

話したいこと3 メソッドチェーンの弱点 基本的にはメソッドチェーンを使って書けるなら書いた方が良いと思ってい るが、弱点もある

Slide 24

Slide 24 text

話したいこと3 メソッドチェーンの弱点 基本的にはメソッドチェーンを使って書けるなら書いた方が良いと思ってい るが、弱点もある デバッグに慣れが必要 途中経過の確認のために.pipeを繋げて中でprint文を打ったりする

Slide 25

Slide 25 text

話したいこと3 メソッドチェーンの弱点 基本的にはメソッドチェーンを使って書けるなら書いた方が良いと思ってい るが、弱点もある デバッグに慣れが必要 途中経過の確認のために.pipeを繋げて中でprint文を打ったりする データ抽出の速度が遅い(かも) df[df[”hoge”] == 1] よりも df.query(“hoge == 1”)の方が5倍くら い遅いこともあった

Slide 26

Slide 26 text

話したいこと3 メソッドチェーンの弱点 基本的にはメソッドチェーンを使って書けるなら書いた方が良いと思ってい るが、弱点もある デバッグに慣れが必要 途中経過の確認のために.pipeを繋げて中でprint文を打ったりする データ抽出の速度が遅い(かも) df[df[”hoge”] == 1] よりも df.query(“hoge == 1”)の方が5倍くら い遅いこともあった Pythonの関数に頼って抽出する場合にちょっと無駄が多い df[”user”].str.contains(“test”) df.query(“user.str.contains(test)”, engine=”python”)

Slide 27

Slide 27 text

X: @yuki_wtz Follow Me!