Python Pandas DataFrame:SettingWithCopyWarning:试图在 DataFrame 的切片副本上设置值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/49728421/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Pandas DataFrame: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame
提问by Matthias
I know there are tons of posts about this warning, but I couldn't find a solution to my situation. Here's my code:
我知道有很多关于此警告的帖子,但我找不到解决我的情况的方法。这是我的代码:
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)
It produces the warning:
它产生警告:
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
SettingWithCopyWarning:试图在 DataFrame 中切片的副本上设置值。尝试使用 .loc[row_indexer,col_indexer] = value 代替
Even though I changed the code as suggested, I still get this warning? All I need to do is to convert the data type of one column.
即使我按照建议更改了代码,我仍然收到此警告?我需要做的就是转换一列的数据类型。
**Remark: ** Originally the column is of type float having one decimal (example: 4711.0). Therefore I change it to integer (4711) and then to string ('4711') - just to remove the decimal.
**备注:** 最初该列是具有一位小数的浮点类型(例如:4711.0)。因此,我将其更改为整数 (4711),然后更改为字符串 ('4711') - 只是为了删除小数。
Appreciate your help!
感谢你的帮助!
Update:The warning was a side effect on a filtering of the original data that was done just before. I was missing the DataFrame.copy(). Using the copy instead, solved the problem!
更新:警告是对之前完成的原始数据过滤的副作用。我错过了 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!
回答by jezrael
I think need copy
and omit loc
for select columns:
我认为需要copy
并省略loc
选择列:
df = df[df['my_col'].notnull()].copy()
df['my_col'] = df['my_col'].astype(int).astype(str)
Explanation:
说明:
If you modify values in df
later you will find that the modifications do not propagate back to the original data (df
), and that Pandas does warning.
如果df
稍后修改值,您会发现修改不会传播回原始数据 ( df
),并且 Pandas 会发出警告。
回答by sudonym
another way is to disable chained assignments, which works on your code without the need to create a copy:
另一种方法是禁用链式赋值,它适用于您的代码 而无需创建副本:
# disable chained assignments
pd.options.mode.chained_assignment = None
回答by Guybrush
If you need to change the data type of a single column, it's easier to address that column directly:
如果您需要更改单个列的数据类型,直接寻址该列会更容易:
df['my_col'] = df['my_col'].astype(int)
Or using .assign
:
或使用.assign
:
df = df.assign(my_col=lambda d: d['my_col'].astype(int))
The .assign
is useful if you only need the conversion once, and don't want to alter your df
outside of that scope.
的.assign
,如果你只需要一次转换,并且不想改变你的是有用df
的是范围之外。