DataFrameの要素の値を更新する際に、SettingWithCopyWarningという警告が出ることがある。
例えば、次のようにユーザのデータを管理するDataFrameにおいて年齢(age)を更新する場合などである。
>>> import pandas as pd >>> df = pd.DataFrame({'name':['ichiro','jiro','saburo'],'age':[30,25,20]},index=['01','02','03']) >>> df age name 01 30 ichiro 02 25 jiro 03 20 saburo >>> df['age']['01'] = +1 __main__:1: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
これは下記のページで説明されているように、df['age']['01']による要素へのアクセスは、2段階になっている。つまり、1段階目では、df['age']でage列から成るDataFrameを取得する。そして、2段階目で、age列のDataFrameの['01']行の要素にアクセスしている。すなわち、DataFrameを行列とみなした場合、行列の要素に直接アクセスしているのではなく、一度列ベクトルを作って、そして、その列ベクトルの所定の行にアクセスしているのである。もし、行数が多い場合は、行数分のメモリの確保とコピーに時間がかかる問題がある。
http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
このSettingWithCopyWarningを回避するためには、.locを使うとよい。つまり、以下のようにすればよい。
>>> df.loc['01','age'] = +1 >>> df age name 01 31 ichiro 02 25 jiro 03 20 saburo
これにより、DataFrameの要素に一段階でアクセスができ、処理が速くなる。また、DataFrameを行列と見なした場合に、行列の('01'、'age')要素にアクセスするのが、.loc['01','age']で書けるため、直感的にもあっているので良い。