Pandas DataFrame:SettingWithCopyWarning:尝试在DataFrame的切片副本上设置值

Mat*_*ias 7 python pandas

我知道有很多关于这个警告的帖子,但我无法找到解决方案.这是我的代码:

df.loc[:, 'my_col'] = df.loc[:, 'my_col'].astype(int)
#df.loc[:, 'my_col'] = df.loc[:, 'my_col'].astype(int).copy()
#df.loc[:, 'my_col'] = df['my_col'].astype(int)
Run Code Online (Sandbox Code Playgroud)

它产生警告:

SettingWithCopyWarning:尝试在DataFrame的切片副本上设置值.尝试使用.loc [row_indexer,col_indexer] = value

即使我按照建议更改了代码,我仍然会收到此警告?我需要做的就是转换一列的数据类型.

**备注:**最初该列的类型为float,具有一位小数(例如:4711.0).因此我将其更改为整数(4711)然后更改为字符串('4711') - 只是为了删除小数.

感谢您的帮助!

更新:该警告对过滤之前完成的原始数据的过滤产生了副作用.我错过了DataFrame.copy().使用副本代替,解决了问题!

df = df[df['my_col'].notnull()].copy()
df.loc[:, 'my_col'] = df['my_col'].astype(int).astype(str)
#df['my_col'] = df['my_col'].astype(int).astype(str) # works too!
Run Code Online (Sandbox Code Playgroud)

jez*_*ael 11

我认为需要copy和省略loc选择列:

df = df[df['my_col'].notnull()].copy()
df['my_col'] = df['my_col'].astype(int).astype(str)
Run Code Online (Sandbox Code Playgroud)

说明:

如果df稍后修改值,您会发现修改不会传播回原始数据(df),并且Pandas会发出警告.


Guy*_*ush 8

如果您需要更改单个列的数据类型,直接寻址该列会更容易:

df['my_col'] = df['my_col'].astype(int)
Run Code Online (Sandbox Code Playgroud)

或者使用.assign

df = df.assign(my_col=lambda d: d['my_col'].astype(int))
Run Code Online (Sandbox Code Playgroud)

.assign如果您只需要转换一次,并且不想df在该范围之外进行更改,那么这很有用。

  • 不,我在使用你的第一行代码时收到了同样的警告。请参阅我原来的帖子中的评论行。第二个不可用,因为列名是静态变量,不能在赋值语句中使用。 (6认同)

sud*_*nym 7

另一种方法是禁用链接分配,该链接分配适用于您的代码, 而无需创建副本

# disable chained assignments
pd.options.mode.chained_assignment = None 
Run Code Online (Sandbox Code Playgroud)