我有这个程序用于演示:
import pandas as pd
d = {'foo':[100, 111, 222],
'bar':[333, 444, 555]}
df = pd.DataFrame(d)
list = [333,444]
dferg = df.loc[df.bar.isin(list)]
dferg['test'] = 123
我收到警告:
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
dferg['test'] = 123
当我改变时:
dferg = df.loc[df.bar.isin(list)]
到
dferg = df.loc[df.bar.isin(list)].copy()
没有更多的警告。但这是最好的方式吗?
答案 0 :(得分:0)
dferg = df.loc[df.bar.isin(list)]
是一个get操作,可以返回视图或副本。调用.copy()
明确告诉它实际上是一个副本,因此不会发出警告。 dferg['test'] = 123
也会修改原始df
,因此如果您想要使用副本而不是视图,pandas会发出警告。
考虑一下您是否希望通过对df
执行的任何分配来修改原始DataFrame dferg
。如果您确实想要修改第一个DataFrame,请将所有内容放在一个.loc
调用中:
df.loc[df.bar.isin(list), 'test'] = 123 # sets 123 in df
否则,就像你说的那样明确地调用copy:
dferg = df.loc[df.bar.isin(list)].copy()
dferg['test'] = 123 # ONLY modifies dferg, not original df