首先咱们来了解一下,df对象的切片操作,这里我就简单举例两种:df.loc[] df[]
df对象是二维的,所以我们在切片的时候一般会取两列索引
import pandas as pd
import numpy as np
dfc = pd.Dataframe({'a': ['one', 'one', 'two',
'three', 'two', 'one', 'six'],
'c': np.arange(7)})
dfc['a'][2]=9
import pandas as pd
import numpy as np
dfc = pd.Dataframe({'a': ['one', 'one', 'two',
'three', 'two', 'one', 'six'],
'c': np.arange(7)})
dfc.loc[2,'a']=9
如果你拿上面这两段代码去运行,你会发现第一个会有一个Warning,当然这只是警告,不是error,还是可以运行的,那为什么会发出这种警告,接下来进入正题
第一个使用的是链式操作,等等,什么是链式操作?
就是说 dfc['a'][2]=9 这一段代码的执行过程中其实是分两步进行,dfc['a']取完切片返回series对象,然而这个对象可能是
临时的副本【不会对原df对象进行修改,那你的9就不知道赋值到哪里去了】
当然也可能是 原先df对象的视图(view)【也就是引用,会改变df对象的数据】, 这个依赖于数组的内存布局,pandas很难预测,于是就直接丢给你一个警告,建议你使用.loc[]
因为.loc[2,'a']是直接一步就取出,不存在链式操作,那是不是用.loc就可以解决一切问题呢?别急,接着往下看,将下面这段代码运行试试
import pandas as pd
import numpy as np
dfc = pd.Dataframe({'a': ['one', 'one', 'two',
'three', 'two', 'one', 'six'],
'c': np.arange(7)})
# dfd['a'][2]=9
b=dfc.loc[:,'a']
b[2]=9
print(b)
你会发现还是报错了,有点糟糕,好吧,这其实是同样的一个错误,这是隐蔽的链式操作,相当于链式操作分成了两步,和前面一个道理,这里就不详细再解释了。那它可以有多隐蔽呢?下面这两段代码中间要是有上千行代码,那可真的很难发现
b=dfc.loc[:,'a'] b[2]=9
那有什么解决办法吗?
让我解释一下这句话先:
SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a Dataframe
这个警告就是说你可能正在对df对象的一个副本进行设置,也就是赋值,这样的话,你的设置就不能对df对象起作用。
但是我们又不一定是为了对原df对象进行修改,我就是想得到一个新的对象,那就可以用copy函数直接生成一个副本
b=dfc.loc[:,'a'].copy() b[2]=9 print(b)
直接使用copy函数返回一个它的副本,或者尽量不那样分布操作,就可以避免上面这种情形
不同的是,对副本的操作不会影响原对象的值
End



