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が出なくなった。