df = pd.DataFrame(np.arange(15).reshape(3, 5), columns=list('ABCDE'))
part_df = df.iloc[:, :3]
part_df.iloc[0, :] = np.zeros(3) #
# 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: https://pandas.pydata.org/pandas
# docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
# self._setitem_single_column(loc, v, pi)
原因在于发生了 chained indexing, 对于part_df的修改并没有作用于df上.
消除warning, 仅需要:
part_df = df.iloc[:, :3].copy()
保证了是对copy的内容进行修改,不作用于原df。
另一个例子:
def do_something(df):
foo = df[['bar', 'baz']] # Is foo a view? A copy? Nobody knows!
# ... many lines here ...
# We don't know whether this will modify df or not!
foo['quux'] = value
return foo
参考文献: