sample.apply(lambda col:sum(col.isnull())/col.size)
group 0.333333
id 0.166667
name 0.166667
score 0.333333
dtype: float64
2. 以指定值填补
pandas数据框提供了fillna方法完成对缺失值的填补,例如对sample表的列score填补缺失值,填补方法为均值:
sample.score.fillna(sample.score.mean())
0 99.0
1 85.0
2 87.0
3 77.0
4 77.0
5 85.0
Name: score, dtype: float64
当然还可以以分位数等方法进行填补:
sample.score.fillna(sample.score.median())
0 99.0
1 82.0
2 87.0
3 77.0
4 77.0
5 82.0
Name: score, dtype: float64
3. 缺失值指示变量
pandas数据框对象可以直接调用方法isnull产生缺失值指示变量,例如产生score变量的缺失值指示变量:
sample.score.isnull()
0 False
1 True
2 False
3 False
4 False
5 True
Name: score, dtype: bool
若想转换为数值0,1型指示变量,可以使用apply方法,int表示将该列替换为int类型。
sample.score.isnull().apply(int)
0 0
1 1
2 0
3 0
4 0
5 1
Name: score, dtype: int64
噪声值指数据中有一个或几个数值与其他数值相比差异较大,又称为异常值、离群值(outlier)。
对于大部分的模型而言,噪声值会严重干扰模型的结果,并且使结论不真实或偏颇,如图5-9。需要在数据预处理的时候清除所以噪声值。噪声值的处理方法很多,对于单变量,常见的方法有盖帽法、分箱法;多变量的处理方法为聚类法。下面进行详细介绍:
1. 盖帽法
盖帽法将某连续变量均值上下三倍标准差范围外的记录替换为均值上下三倍标准差值,即盖帽处理
Python中可自定义函数完成盖帽法。如下所示,参数x表示一个pd.Series列,quantile指盖帽的范围区间,默认凡小于百分之1分位数和大于百分之99分位数的值将会被百分之1分位数和百分之99分位数替代:
def cap(x,quantile=[0.01,0.99]):
“”"盖帽法处理异常值
Args:
x:pd.Series列,连续变量
quantile:指定盖帽法的上下分位数范围
“”"
生成分位数
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)
现生成一组服从正态分布的随机数,sample.hist表示产生直方图,更多绘图方法会在下一章节进行讲解:
sample = pd.DataFrame({‘normal’:np.random.randn(1000)})
sample.hist(bins=50)
对pandas数据框所有列进行盖帽法转换,可以以如下写法,从直方图对比可以看出盖帽后极端值频数的变化。
new = sample.apply(cap,quantile=[0.01,0.99])
new.hist(bins=50)
2. 分箱法
分箱法通过考察数据的“近邻”来光滑有序数据的值。有序值分布到一些桶或箱中。
分箱法包括等深分箱:每个分箱中的样本量一致;等宽分箱:每个分箱中的取值范围一致。直方图其实首先对数据进行了等宽分箱,再计算频数画图。
比如价格排序后数据为:4、8、15、21、21、24、25、28、34
将其划分为(等深)箱:
-
箱1:4、8、15
-
箱2:21、21、24
-
箱3:25、28、34
将其划分为(等宽)箱:
-
箱1:4、8
-
箱2:15、21、21、24
-
箱3:25、28、34
分箱法将异常数据包含在了箱子中,在进行建模的时候,不直接进行到模型中,因而可以达到处理异常值的目的。
pandas的qcut函数提供了分箱的实现方法,下面介绍如何具体实现。
**等宽分箱:**qcut函数可以直接进行等宽分箱,此时需要的待分箱的列和分箱个数两个参数,如下所示,sample数据的int列为从10个服从标准正态分布的随机数:
sample =pd.DataFrame({‘normal’:np.random.randn(10)})
sample
normal
0 0.065108
1 -0.597031
2 0.635432
3 -0.491930
4 -1.894007
5 1.623684
6 1.723711
7 -0.225949
8 -0.213685
9 -0.309789
现分为5箱,可以看到,结果是按照宽度分为5份,下限中,cut函数自动选择小于列最小值一个数值作为下限,最大值为上限,等分为五分。结果产生一个Categories类的列,类似于R中的factor,表示分类变量列。
此外弱数据存在缺失,缺失值将在分箱后将继续保持缺失,如下所示:
pd.cut(sample.normal,5)
0 (-0.447, 0.277]
1 (-1.17, -0.447]
2 (0.277, 1.0]
3 (-1.17, -0.447]
4 (-1.898, -1.17]
5 (1.0, 1.724]
6 (1.0, 1.724]
7 (-0.447, 0.277]
8 (-0.447, 0.277]
9 (-0.447, 0.277]
Name: normal, dtype: category
Categories (5, interval[float64]): [(-1.898, -1.17] < (-1.17, -0.447] < (-0.447, 0.277] < (0.277, 1.0] < (1.0, 1.724]]
这里也可以使用labels参数指定分箱后各个水平的标签,如下所示,此时相应区间值被标签值替代:
pd.cut(sample.normal,bins=5,labels=[1,2,3,4,5])
0 1
1 1
2 2
3 2
4 3
5 3
6 4
7 4
8 5
9 5
Name: normal, dtype: category
Categories (5, int64): [1 < 2 < 3 < 4 < 5]
标签除了可以设定为数值,也可以设定为字符,如下所示,将数据等宽分为两箱,标签为‘bad’,‘good’:
pd.cut(sample.normal,bins=2,labels=[‘bad’,‘good’])
0 bad
1 bad
2 bad
3 bad
4 bad
5 good
6 good
7 good
8 good
9 good
Name: normal, dtype: category
Categories (2, object): [bad < good]
等深分箱:等深分箱中,各个箱的宽度可能不一,但频数是几乎相等的,所以可以采用数据的分位数来进行分箱。依旧以之前的sample数据为例,现进行等深度分2箱,首先找到2箱的分位数:
sample.normal.quantile([0,0.5,1])
0.0 0.0
0.5 4.5
1.0 9.0
Name: normal, dtype: float64
做了那么多年开发,自学了很多门编程语言,我很明白学习资源对于学一门新语言的重要性,这些年也收藏了不少的Python干货,对我来说这些东西确实已经用不到了,但对于准备自学Python的人来说,或许它就是一个宝藏,可以给你省去很多的时间和精力。
别在网上瞎学了,我最近也做了一些资源的更新,只要你是我的粉丝,这期福利你都可拿走。
我先来介绍一下这些东西怎么用,文末抱走。
(1)Python所有方向的学习路线(新版)
这是我花了几天的时间去把Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
最近我才对这些路线做了一下新的更新,知识体系更全面了。
(2)Python学习视频
包含了Python入门、爬虫、数据分析和web开发的学习视频,总共100多个,虽然没有那么全面,但是对于入门来说是没问题的,学完这些之后,你可以按照我上面的学习路线去网上找其他的知识资源进行进阶。
(3)100多个练手项目
我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了,只是里面的项目比较多,水平也是参差不齐,大家可以挑自己能做的项目去练练。
(4)200多本电子书
这些年我也收藏了很多电子书,大概200多本,有时候带实体书不方便的话,我就会去打开电子书看看,书籍可不一定比视频教程差,尤其是权威的技术书籍。
基本上主流的和经典的都有,这里我就不放图了,版权问题,个人看看是没有问题的。
(5)Python知识点汇总
知识点汇总有点像学习路线,但与学习路线不同的点就在于,知识点汇总更为细致,里面包含了对具体知识点的简单说明,而我们的学习路线则更为抽象和简单,只是为了方便大家只是某个领域你应该学习哪些技术栈。
(6)其他资料
还有其他的一些东西,比如说我自己出的Python入门图文类教程,没有电脑的时候用手机也可以学习知识,学会了理论之后再去敲代码实践验证,还有Python中文版的库资料、MySQL和HTML标签大全等等,这些都是可以送给粉丝们的东西。
这些都不是什么非常值钱的东西,但对于没有资源或者资源不是很好的学习者来说确实很不错,你要是用得到的话都可以直接抱走,关注过我的人都知道,这些都是可以拿到的。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!