29

この問題に関連する多くの質問と回答を調べましたが、予期しない場所でこのスライス警告のコピーが表示されていることがわかりました。また、以前は正常に実行されていたコードで発生しているため、何らかの更新が原因である可能性があるのではないかと考えています.

たとえば、これは、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/samliienfeld/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()ますか? これを行うためのよりクリーンな方法があるはずです。洞察や助けをいただければ幸いです。

4

1 に答える 1

35
 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。その後、それに割り当てようとします。これがエラーを投げているものです。代わりにこれを使用してください:

 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_dfその属性には真の値がありis_copyます。それに割り当てようとすると、パンダは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]
于 2016-08-08T17:48:02.577 に答える