すのふら

すのふら

日々の備忘録

Python pandasで「A value is trying to be set on a copy of a slice from a DataFrame.」が出力される

仕事でツールを作ろうと思ってjupyter notebook上で実装していた際、以下のWarningメッセージが出てきた。
(めんどいから)スルーでもいいのかなーとも思ったが、気持ち悪いので対応したのでメモしておく。

pandas version:0.20.1

C:\[install先]\Anaconda3\lib\site-packages\ipykernel\__main__.py:32: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
 
See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy



対応方法

以下の実装を実行すると出力する。

        # あるDataFrameから対象の列だけ抽出する。
        df_tmp = df_mached[["a", "b", "c", "d"]]
        
        # 存在しない列名を指定して、その列を追加して値を代入して列を追加する。
        df_tmp["e"]= "hogehoge"


基本的な対応はこのqiitaの記載のとおりで、copy()する実装を加える。
qiita.com

        # あるDataFrameから対象の列だけ抽出する。
        df_tmp = df_mached[["a", "b", "c", "d"]]
        df_tmp = df_tmp.copy()
        # 存在しない列名を指定して、その列を追加して値を代入して列を追加する。
        df_tmp["e"]= "hogehoge"



そもそもSettingWithCopyWarningって何か。

pandasの公式ドキュメント上だと、

Pandas has the SettingWithCopyWarning because assigning to a copy of a slice is frequently not intentional, but a mistake caused by chained indexing returning a copy where a slice was expected.
Indexing and Selecting Data — pandas 0.23.4 documentation



「スライスのコピーへの割り当ては意図的なものではなく、スライスが期待される場所にコピーされたインデックスを返すことによるミスです。」とgoogle翻訳

おそらく元のDataFrameのスライス上"e"は存在していないのに、直接そこを変更しようとしたからだと思われる。
現にcopy()してあげると、元のDataFrameとは切り離されるので、Warningが出なくなった。