使用pandas而出现的警告SettingWithCopyWarning

0. 如何解决

简单来说就是加个 .copy() 即可
也就是强制让pandas给某个dataframe创建一个副本,表明我绝对是在新的一个dataframe上操作,而不是在原有的dataframe上操作

下面举例如何复现这个警告,然后说明下为什么出现这个警告,最后会给出一个解决方法来解决这个警告

1. 如何复现如下警告(运行如下代码将会出现SettingWithCopyWarning这个警告)

# 首先引入pandas这个库是必须的
import pandas as pd

# 然后建一个简单的DataFrame来举例说明
df = pd.DataFrame({'c1':[1,2,3], 'c2':[100,200,300]})

# 可以将这个简单的DataFrame打印出来看看是个什么样子
print('df:\n', df)

# 接下来,简单地复现这个警告
# 也就是取出df的'c1'这一列,然后改变其第2行的值即可
df1 = df[['c1']]
df1['c1'][1] = 0


# 在改变df1的c1列的第2行后,将会出现类似下面的警告:
# Warning (from warnings module):
# File ......一些信息......
# SettingWithCopyWarning: 
# A value is trying to be set on a copy of a slice from a DataFrame
# See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy

# 当然,可以打印一下df1,看看现在的df1有何变化(注:成功改变了这个df1中的值,没有改变df中的值)
print('df1:\n', df1)

2. 解释说明为什么执行上述代码后会出现SettingWithCopyWarning这个警告

因为pandas不知道你是想在原有的df上的第c1列进行操作(影响原有的df)
还是想提取出c1这一列并复制一份副本,然后在这个副本上进行操作(不影响原有的df)

3. 解决办法,加一个.copy(),表面我想提取出c1这一列并复制一份副本,然后在这个副本上进行操作(不影响原有的df)

# 首先,删除上面的三句代码
df1 = df[['c1']]
df1['c1'][1] = 0
print('df1:\n', df1)
# 然后
#
加一个copy()就行,表明我绝对是在新的一个dataframe上操作,而不是在原有的dataframe上操作 # copy()就是强制让pandas创建一个副本 df2 = df[['c1']].copy() # 现在改变c1列的第2行的值,就不会出现SettingWithCopyWarning这个警告了 df2['c1'][1] = 0

4. 完整的不出现警告的代码

import pandas as pd

df = pd.DataFrame({'c1':[1,2,3], 'c2':[100,200,300]})

print('df:\n', df)

# 用.copy()
df1 = df[['c1']].copy()
df1['c1'][1] = 0

print('df1:\n', df1)

猜你喜欢

转载自www.cnblogs.com/Alan-LJP/p/12810195.html