这个问题是切片 DataFrame 会在切片和原始 DataFrame 之间创建一个weakref。这会在您进行分配时触发下一行的警告。
import pandas as pd
df = pd.DataFrame([0,1,1,1,2])
r = df[df.isin([1]).all(1)]
r['new_col'] = False
#<ipython-input-210-d5f9bda478c4>:9: SettingWithCopyWarning: ...
您可以使用内置方法._is_copy 验证是否存在弱引用
df = pd.DataFrame([0,1,1,1,2])
r = df[df.isin([1]).all(1)]
r._is_copy
#<weakref at 0x142b10e00; to 'DataFrame' at 0x14361ed00>
而打破这一点最简单的方法是使用.copy() 强制进行深层复制,使r 与df 没有任何关系,从而消除警告。
r = df[df.isin([1]).all(1)].copy()
r._is_copy
#None
r['new_col'] = False
# No warning!
最后,这个警告经常似乎被击中或错过,但这是因为许多pandas操作返回一个新对象,所以如果切片和分配很可能这些操作本身会破坏弱引用,从而阻止警告。例如,像乘以 2 这样的简单操作会创建一个新对象,而您不会收到任何警告。
df = pd.DataFrame([0,1,1,1,2])
r = df[df.isin([1]).all(1)]
print(r._is_copy)
#<weakref at 0x13e6ad0e0; to 'DataFrame' at 0x1436227c0>
r = r*2 # Breaks the reference
print(r._is_copy)
# None
r['new_col'] = False
# No warning!