数据录入
df=pd.DataFrame({'id':[1,1,1,3,4,5],'name':['Bob','Bob','Mark','Miki','Sully','Rose'],
'score':[99,99,87,77,77,np.nan],
'group':[1,1,1,2,1,2]})
数据处理是数据分析的必备环节,在进行分析过程中,会有很多不符合分析要求的数据,例如重复、错误、缺失、异常类数据。捋以下数据处理方法。
一、重复值处理
直接删除是重复数据处理的主要方法。pandas提供查看、处理重复数据的方法duplicated和drop_duplicates。
df[df.duplicated()]#发现重复数据
df.drop_duplicates()#进行去重
df.drop_duplicates('id')#按照某列进行去重
二、缺失值处理
首先,需要根据
业务理解
处理缺失值,弄清楚缺失值产生的原因是故意缺失还是随机缺失,再通过一些业务经验进行填补。缺失值处理总括图如下。
在下图中展示了中位数填补缺失值和缺失指示哑变量的生成过程。
-
查看缺失情况
方法一:
df_count = df.count()
na_count = len(df) - df_count#缺失个数
na_rate = na_count/len(df)#缺失比例
a=na_rate.sort_values(ascending=False) #排序
a1=pd.DataFrame(a)#转换成字典形式
方法二:
在Python中可以构造一个lambda函数来查看缺失值
df.apply(lambda col:sum(col.isnull())/col.size)
#lambda函数中,sum(col.isnull())表示当前列有多少缺失,col.size表示当前列总共多少行数据
-
以指定值填补
df.score.fillna(sample.score.mean())
#利用fillna方法完成对缺失值的填补
df.score.fillna(sample.score.median())
-
缺失指示哑变量
df.score.isnull()
#调用方法isnull产生缺失值指示变量
df.score.isnull().apply(int)
#若想转换为数值0,1型指示变量,可以使用apply方法,int表示将该列替换为int类型
异常值处理
又称离群值、极值、噪声值。对于大部分的模型而言,异常值会严重干扰模型的结果,并且使结论不真实或偏颇。需要在数据处理的时候清除异常值。异常值的处理方法很多,概括如图:
1.盖帽法
What
How
Python中可自定义函数完成盖帽法。如下所示,参数x表示一个pd.Series列,quantile指盖帽的范围区间,默认凡小于百分之1分位数和大于百分之99分位数的值将会被百分之1分位数和百分之99分位数替代:
def cap(x,quantile=[0.01,0.99]):
# 生成分位数
Q01,Q99=x.quantile(quantile).values.tolist()
# 替换异常值为指定的分位数
if Q01 > x.min():
x = x.copy()
x.loc[x<Q01] = Q01
if Q99 < x.max():
x = x.copy()
x.loc[x>Q99] = Q99
return(x)
Example
1.现生成一组服从正态分布的随机数
df = pd.DataFrame({'normal':np.random.randn(1000)})
df.hist(bins=50)
2.盖帽法处理
new = df.apply(cap,quantile=[0.01,0.99])
new.hist(bins=50)
2.分箱法
What
分箱法包括等深分箱:每个分箱中的样本量一致;等宽分箱:每个分箱中的取值范围一致。直方图其实首先对数据进行了等宽分箱,再计算频数画图。
比如年龄排序后数据为:6、8、15、21、21、24、25、28、34
将其划分为(等深)箱:
箱1:6、8、15
箱2:21、21、24
箱3:25、28、34
将其划分为(等宽)箱:
箱1:6、8
箱2:15、21、21、24
箱3:25、28、34
How
现生成一组服从正态分布的随机数:
df =pd.DataFrame({'normal':np.random.randn(10)})
1、等宽分箱:cut函数可以直接进行等宽分箱,此时需要的待分箱的列和分箱个数两个参数。
pd.cut(df.normal,bins=5,labels=[1,2,3,4,5])
#标签除了可以设定为数值,也可以设定为字符
pd.cut(df.normal,bins=2,labels=['value','devalue'])
现分为5箱,可以看到,结果是按照宽度分为5份,下限中,cut函数自动选择小于列最小值一个数值作为下限,最大值为上限,等分为五分。结果产生一个Categories类的列。labels参数指定分箱后各个水平的标签,此时相应区间值被标签值替代。
2、等深分箱:各个箱的宽度可能不一,但频数是几乎相等的,所以可以采用数据的分位数来进行分箱。
#现进行等深度分2箱,首先找到2箱的分位数
df.normal.quantile([0,0.5,1])
#在bins参数中设定分位数区间,include_lowest=True参数表示包含边界最小值包含数据的最小值
pd.cut(df.normal,bins=df.normal.quantile([0,0.5,1]),include_lowest=True)
#此外也可以加入label参数指定标签
pd.cut(df.normal,bins=df.normal.quantile([0,0.5,1]),include_lowest=True,labels=['value','devalue'])
3. 多变量异常值处理-聚类法
常用检查异常值聚类算法为K-means聚类