目录
0、Pandas 常见的小技巧
一、SettingWithCopyWarning 警告
详情如下:
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
See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
self.obj[item_labels[indexer[info_axis]]] = value
原因:链式赋值,可以理解2次及2次以上链式引用赋值
参考文章: Pandas的SettingWithCopyWarning警告出现的原因和如何避免
import pandas as pd
import numpy as np
import re
df1 = pd.DataFrame(np.random.random((10,2)),columns=['A',"B"])
print(df1)
out:
A B
0 0.531017 0.257831
1 0.160552 0.732588
2 0.941906 0.386234
3 0.750562 0.222612
4 0.073861 0.424672
5 0.303846 0.551761
6 0.128234 0.022858
7 0.901164 0.124204
8 0.846696 0.650858
9 0.584505 0.159172
df2 = df1.loc[df1.loc[:,"A"] < 0.6] # 第一次引用
df2.loc[:,"B"] = 100000 # 第二次引用
# 此时会报一个警告,而且df2改变了,而df1 没有改变,可以说df2是开辟了一块新的内存空间,执行了copy操作
print(df1)
A B
0 0.997374 0.982859
1 0.432220 0.347049
2 0.691235 0.426083
3 0.826183 0.328331
4 0.642627 0.812556
5 0.643806 0.806637
6 0.072150 0.185087
7 0.089435 0.690611
8 0.808309 0.872907
9 0.824422 0.023211
print(df2)
A B
1 0.432220 100000
6 0.072150 100000
7 0.089435 100000
# 下面这个也是链式赋值,和上面结果一样
df6 = pd.DataFrame(np.random.random((10,2)),columns=['A',"B"])
print(df1)
df6.loc[df1.loc[:,"A"] < 0.6].loc[:,"B"] = 100000
print(df6)
# 这个例子才是正确的语法
df6 = pd.DataFrame(np.random.random((10,2)),columns=['A',"B"])
print(df1)
df6.loc[df1.loc[:,"A"] < 0.6,"B"] = 100000
print(df6)
A B
0 0.565020 0.653496
1 0.611672 100000.000000
2 0.679511 0.841419
3 0.725681 0.112626
4 0.341104 0.534939
5 0.664592 0.090816
6 0.127283 100000.000000
7 0.823812 100000.000000
8 0.263783 0.557775
9 0.795078 0.095603
这里总结一下pandas的这个问题:
避免任何形式的链式赋值,有可能会报warning也有可能不会报。而且即使报了,可能有问题,也可能没问题。
如果需要用到多级选取,则用loc
如果需要用到拷贝,则直接加copy()函数