Python

【Python】pandasでDataFrameの値渡しをする方法

【Python】pandasでDataFrameの値渡しをする方法

んー
どうしたの?
なんかpandasでFataFrameを加工してたら、何故か触ってない方のDataFrameの中身が勝手に変わっちゃって・・・
それ、勝手に変わったDataFrameって加工してるDataFrameの元データだったりする?
そうだけど何か?
あー、原因わかったわ

Pythonのデータ処理によく使われるDataFrame。

表形式のCSVやExcelのデータを読むことができ、集計や加工にとても重宝する。

しかし気をつけて使わないと自分の意図しないタイミングでデータが書き換わってしまうことがあるかもしれない。

今回はpandasでDataFrameの中身が変わってしまう原因と、「pandasでDataFrameの値渡しをする方法」について解説する。

この記事を書いている人


システムエンジニア、AIエンジニアと、IT業界で10年以上働いている中堅。PythonとSQLが得意。機械学習や予測の前処理や後処理でpandasをよく使う。

記事を読むメリット

  • pandasでDataFrameの中身が変わってしまう原因と、pandasでDataFrameの値渡しをする方法がわかる

  • pandasでDataFrameの中身が変わってしまう原因

    pandasでDataFrameの中身が変わってしまう原因。

    それは参照渡ししたDataFrameを編集してしまっているから。

    「参照渡し」ってなんだっけ?
    変数を渡したときの挙動の違いですね
    a = b とした時、「値渡し」ならbは「aと同じ値を持っているけどコピーされた別の存在」なので、bを編集してもaに変化はない
    でも「参照渡し」なら、bは「変数名が違うだけでaと同じ存在」なのでbを編集したらaも変化する。



    具体的にコードにすると以下のようになる。

    import pandas as pd
    
    def change_df(df):
        df["c3"].iloc[1] = 44
        return
    
    # ---- passed by reference ----
    
    data_list1 = [
    [1,2,3],
    [2,3,4],
    [3,4,5]
    ]
    col_list = ["c1","c2","c3"]
    df = pd.DataFrame(data=data_list1, columns=col_list)
    print(df)
    
    #    c1  c2  c3
    # 0   1   2   3
    # 1   2   3   4
    # 2   3   4   5
    
    print("df2 = df")
    df2 = df
    
    print('df2["c1"].iloc[1] = 22')
    df2["c1"].iloc[1] = 22
    
    print("df")
    print(df)
    print("df2")
    print(df2)
    
    # df
    #    c1  c2  c3
    # 0   1   2   3
    # 1  22   3   4
    # 2   3   4   5
    # df2
    #    c1  c2  c3
    # 0   1   2   3
    # 1  22   3   4
    # 2   3   4   5
    
    print('change_df(df2)')
    change_df(df2)
    print("df")
    print(df)
    print("df2")
    print(df2)
    
    # df
    #    c1  c2  c3
    # 0   1   2   3
    # 1  22   3  44
    # 2   3   4   5
    # df2
    #    c1  c2  c3
    # 0   1   2   3
    # 1  22   3  44
    # 2   3   4   5
    

    df2 = df として df2 というDataFrameを作ってdf2の中身を書き換えているが、参照渡しで本体はdf同じであるためprintするとdfも同じように書き換わっている。

    ではどうすれば参照渡しではなく df2 を別のDataFrameとして作ることができるのか。



    pandasでDataFrameの値渡しをする方法

    pandasでDataFrameを参照渡しではなく値渡しする方法。

    それは copy() メソッドを使うことだ。

    copy() メソッドを使うと、値だけコピーした別の変数を作ることができる。

    具体的には以下の通り。

    # ---- passed by value ----
    
    print('Initialize df')
    
    data_list1 = [
    [1,2,3],
    [2,3,4],
    [3,4,5]
    ]
    col_list = ["c1","c2","c3"]
    df = pd.DataFrame(data=data_list1, columns=col_list)
    print(df)
    
    #    c1  c2  c3
    # 0   1   2   3
    # 1   2   3   4
    # 2   3   4   5
    
    print("df2 = df.copy()")
    df2 = df.copy()
    
    print('df2["c1"].iloc[1] = 22')
    df2["c1"].iloc[1] = 22
    
    print("df")
    print(df)
    print("df2")
    print(df2)
    
    # df
    #    c1  c2  c3
    # 0   1   2   3
    # 1   2   3   4
    # 2   3   4   5
    # df2
    #    c1  c2  c3
    # 0   1   2   3
    # 1  22   3   4
    # 2   3   4   5
    
    print('change_df(df2)')
    change_df(df2)
    print("df")
    print(df)
    print("df2")
    print(df2)
    
    # df
    #    c1  c2  c3
    # 0   1   2   3
    # 1   2   3   4
    # 2   3   4   5
    # df2
    #    c1  c2  c3
    # 0   1   2   3
    # 1  22   3  44
    # 2   3   4   5
    


    df2を作る際に df2 = df.copy() とすることで、dfの中身をコピーした別の変数(インスタンス)としてdf2を作ることができる。

    df2はdfとは別の存在なので、中身を編集してもdf自体に影響はない。



    【Python】pandasでDataFrameの値渡しをする方法 まとめ

    pandasでDataFrameの中身が変わってしまう原因は参照渡ししたDataFrameを編集してしまっているから。

    DataFrameの値渡しをするには copy() メソッドを使って別の変数(インスタンス)を作成すると元となったDataFrameに影響しないDataFrameを作成できる。




    他にもpandasでExcelを読み書きする方法の記事もあるので、気になったら参考にしてほしい。

    ITipsと同じようなブログを作る方法

    ブログに興味がありますか?

    もしブログに興味がある場合は↓このページ↓を参考にすれば、ITipsと同じ構成でブログを作ることができます

    サーバー、ドメイン、ASPと【ブログに必要なものは全て】このページに書きました。
    同じ構成でブログ作るのはいいけど、記事はマネしないでネ (TДT;)

    ランキング参加中

    にほんブログ村 IT技術ブログへ

    他にもブログやSNSで紹介してくれると励みになります。

    はてブのコメントで酷評されると泣きます(´;ω;`)

    -Python
    -,

    © 2024 ITips