web-dev-qa-db-ja.com

混乱の再:pandasデータフレームのスライスの警告の警告

この問題に関連する一連の質問と回答を確認しましたが、予期しない場所でこのスライスの警告のコピーが表示されることがわかります。また、以前は問題なく動作していたコードが表示されるため、なんらかの更新が原因であるのではないかと思います。

たとえば、これはコードセットで、Excelファイルをpandas DataFrameに読み込んで、 _df[[]]_構文。

_ izmir = pd.read_Excel(filepath)
 izmir_lim = izmir[['Gender','Age','MC_OLD_M>=60','MC_OLD_F>=60','MC_OLD_M>18','MC_OLD_F>18','MC_OLD_18>M>5','MC_OLD_18>F>5',
               'MC_OLD_M_Child<5','MC_OLD_F_Child<5','MC_OLD_M>0<=1','MC_OLD_F>0<=1','Date to Delivery','Date to insert','Date of Entery']]
_

ここで、この_izmir_lim_ファイルにさらに変更を加えると、スライスのコピーの警告が発生します。

_izmir_lim['Age'] = izmir_lim.Age.fillna(0)
izmir_lim['Age'] = izmir_lim.Age.astype(int)
_

/Users/samlilienfeld/anaconda/lib/python3.5/site-packages/ipykernel/main.py:2:SettingWithCopyWarning:DataFrameからのスライスのコピーに値を設定しようとしています。代わりに.loc [row_indexer、col_indexer] = valueを使用してみてください

_df[[]]_列のサブセットがデフォルトでコピーを返すと思ったので混乱しています。エラーを抑制する唯一の方法は、df[[]].copy()を明示的に追加することです。過去にはそうする必要はなく、スライスエラーのコピーを生成しなかったと私は誓ったでしょう。

同様に、データフレームで関数を実行して特定の方法でフィルターする他のコードがあります。

_def lim(df):
if (geography == "All"):
    df_geo = df
else:
    df_geo = df[df.center_JO == geography]

df_date = df_geo[(df_geo.date_survey >= start_date) & (df_geo.date_survey <= end_date)]

return df_date

df_lim = lim(df)
_

この時点以降、_df_lim_の値を変更すると、スライスエラーのコピーが発生します。私が見つけた唯一の回避策は、関数呼び出しを次のように変更することです。

_df_lim = lim(df).copy()
_

これは私には間違っているようです。何が欠けていますか?これらのユースケースはデフォルトでコピーを返すはずであり、これらのスクリプトを最後に実行したときに、これらのエラーが発生していないことを確認できたはずです。
あちこちに.copy()を追加し始める必要がありますか?これを行うためのよりクリーンな方法があるはずです。どんな洞察や助けでも大歓迎です。

18
Sam Lilienfeld
 izmir = pd.read_Excel(filepath)
 izmir_lim = izmir[['Gender','Age','MC_OLD_M>=60','MC_OLD_F>=60',
                    'MC_OLD_M>18','MC_OLD_F>18','MC_OLD_18>M>5',
                    'MC_OLD_18>F>5','MC_OLD_M_Child<5','MC_OLD_F_Child<5',
                    'MC_OLD_M>0<=1','MC_OLD_F>0<=1','Date to Delivery',
                    'Date to insert','Date of Entery']]

izmir_limizmirのビュー/コピーです。その後、それに割り当てようとします。これがエラーの原因です。代わりにこれを使用してください:

 izmir_lim = izmir[['Gender','Age','MC_OLD_M>=60','MC_OLD_F>=60',
                    'MC_OLD_M>18','MC_OLD_F>18','MC_OLD_18>M>5',
                    'MC_OLD_18>F>5','MC_OLD_M_Child<5','MC_OLD_F_Child<5',
                    'MC_OLD_M>0<=1','MC_OLD_F>0<=1','Date to Delivery',
                    'Date to insert','Date of Entery']].copy()

次の方法で別のデータフレームから新しいデータフレームを「作成」するときはいつでも:

new_df = old_df[list_of_columns_names]

new_dfis_copy属性。割り当てようとすると、pandasはSettingWithCopyWarningをスローします。

new_df.iloc[0, 0] = 1  # Should throw an error

これはいくつかの方法で克服できます。

オプション1

new_df = old_df[list_of_columns_names].copy()

オプション#2(@ayhanがコメントで提案したとおり)

new_df = old_df[list_of_columns_names]
new_df.is_copy = None

オプション#3

new_df = old_df.loc[:, list_of_columns_names]
18
piRSquared