动手学数据分析 第二章之数据清洗及特征处理

今天周六,本来文章应该早点儿开始完成的。事实证明,一到周末,我的拖延症懒癌就特别容易犯。既没有比往常开始的时间早,也没有往常写得看得多,摊手。

起步走,我们拿到数据的时候,通常数据你想不仅有你想不到的问题,当然也有你能想得到的问题。

缺失值和异常值是普遍的存在,缺失值的含义是对于某一列字段来讲,存在个别行的该字段无值。缺失值(官方定义:粗糙数据中由于缺少信息而造成的数据聚类、分组、删失或者截断。它指的是现有数据中某个或某些属性的值是不完全的),缺失值缺失的原因可能是业务原因,系统调用原因,落库数据中间出现bug等等;异常值的含义是相对概念,也叫离群值,判断依据实际情况,业务知识及实际需要而定。指的是对于某一列字段来说,偏离数据集中度很多的数据。我这个说的有些云里雾里,我去百度以下官方定义。异常值统计学上的定义是指样本中的个别值明显偏离它或它们所属样本的其它观测值。百度百科也给了异常值一个可用公式表达的定义:一组测定值中与平均值的偏差超过两倍标准差的测定值,与平均值的偏差超过三倍标准差的测定值称为高度异常的异常值。

本小节的主要内容有三个:

1、缺失值的观测和处理

2、重复值的观测和处理

3、特征的观测和处理。

相较而言我比较好奇的当然是重复值的观测和处理,这里定义的重复值是否是存在某两行完全一样的数据,叫做重复值吗?感觉如果看单个字段的重复值,并没有实际的意义,当然类别型文本变量除外,如果这样说类别型数值变量,也该被排除在外,那其实看变量的重复值也就在观察单值率有意义,其它时候这个重复值怎么处理也是个问题。嗯,我还没有开始看答案,只是在拿到任务的初期,有些许疑问,等我看到解答之后,才能猜测这个重复值的观测和处理的真实意图。

1.1查看单个特征缺失值的个数

1.2查看所有特征的缺失值个数

涉及到的方法是isnull().sum(),同时df.info也是一个好方法,可以看到各特征非缺失的情况。

1.3对缺失值进行处理

在我自己的认知里,处理缺失值的方法有3种:

1、删除 这里删除指的是整个属性的删除或者是整条记录的删除。整条记录的删除一般很少做,除非你很确定这条记录确实是因为异常导致的整条记录出现大面积变量的缺失,整个属性如果在数据集上的缺失率比较高,比如超过99%,如果着实不是因为变量定义,而且该变量的缺失并不存在明显的业务含义,一般情况下都会考虑删除;

2、填充,就是用一定的值值替换掉缺失值,从而使信息完备化;我也是叫孤陋寡闻的,在我自己的印象里,一般会选择平均值、中位数、频数最大的某值--众数而言(当然这个是仅仅是针对某个属性)填充。崇尚好学的我去请教了度娘,度娘果然会教导我重新做人,刷新我的认识:

     通常基于统计学原理,根据样本中其余对象的取值分布情况来对缺失值进行填充

      这个人很懒,感觉写不下去了。毕竟百度上的填充方法我大多部分没有用过。考虑到我写这个栏目的主要目的使学习Python,后面如果有机会总结我工作经历的话,我可以写一个项目然后把缺失值的处理单独写一篇文章,好好研究一下。果然写记录是有好处的,要不然我就以为数据处理方面我什么都是随手拈来,呵呵哒。

3、不处理 这里是认为数据的空值也是有一定的含义的,它之所以为空,是因为它不同于其它任何数据。所以把空值当作一个特殊的属性值来处理,不同于其它属性值。一方面因为补齐处理只是将未知值补以我们主观估计值,不一定完全符合客观事实,在对不完备的信息进行补齐处理的同时,其实我们在一定程度上也改变了原有的信息系统;另一方面对空值不正确的填充,也会引入新的噪声到数据信息中。

在看别人的文章里,会把将缺失值统一赋值于一个值叫做特殊值填充。因为我常常把缺失值单独分为一组,所以在我的印象中我一直以为这叫不处理。但估计是要对自己纠偏了。拿个我平常最常遇到的情况说一下吧,我们新接了一个数据源,对于我们的优质客群,我们并不准备调用此数据源。对于非优质客群,会接入此数据源用于辅助决策,但是该数据源毕竟与我们自己的客户存在不交叉的部分,所以即使接入数据源也有可能返回的值为空。这其实就会存在两种情况的缺失,而且明显第一种缺失相较第二种缺失我们对客户的把握会更精准,第二种缺失我们就要考虑该数据源的源头及其客户来源,从而会帮助我们对缺失客群有更好的了解。

检索空值的数据记录,如下可看出None没有np.nan好用。因为数据列读取数据之后,数值列的数据类型会变成float64,用None会读取不到,比较的时候最好用np.nan。

然后我对特定的列做fillna,就光荣报错了。但我也比较执着,哈哈。

【参考】https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.dropna.html

【参考】https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.fillna.html

这两个网址后面应该还需要斗智斗勇。

终于来到第二部分了,偷瞄了两眼答案,是相较于完全重复的两行来说的,这样就可以理解了。

2.1 查看重复值、df[df.duplicated].head()

2.2 删除整行缺失的记录 df.drop_duplicates().head()

可以看到在原数据集上并没有删除整行缺失的记录,我在这里考虑增加了参数inplace=True.事实证明达到了删除整行缺失记录的目的,就是需要记得df.drop_duplicates(inplace=True)是没有返回值的。

第三部分是特征观察和处理。

特征大致分为两类:数值型特征(离散型数值特征、连续型数值特征)和文本型特征(类别型文本特征)。连续型变量一般可以直接用于训练模型,但有时候为了模型的稳定性和鲁棒性会对连续变量进行离散化。文本型特征往往需要转化为数值型特征才能进行建模分析。

变量按其数值表现是否连续,分为连续变量和离散变量。离散型变量指的是变量可以按一定顺序一一列举。

3.1 对数值型变量进行离散化

分箱操作其实就是将数值型变量进行离散化,将多状态的离散型状态合并成少状态的过程。

将年龄平均分为5组,并分别用类别型变量12345表示。


将连续变量Age划分为[0,5) [5,15) [15,30) [30,50) [50,80)五个年龄段,并分别用类别变量12345表示.

train['AgeBand'] = pd.cut(train['Age'],[0,5,15,30,50,80],labels = ['1','2','3','4','5'])

将连续变量Age划分为10%、30% 、50% 、70%、 90% 五个年龄段,并分别用类别变量12345表示. 

这个按百分数来划分的年龄段我并没有看懂,因为上面的那个代码可以晓得80是最大值,但是这个90%代表的是什么呢。

train['Age_bucket3'] = pd.qcut(train['Age_n'], [0, 0.1, 0.3, 0.5, 0.7, 0.9], labels = ['1', '2', '3', '4', '5'])

【参考】https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.cut.html

【参考】https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.qcut.html

因为我今天还在完成昨天的任务,我只能后面把我的这个疑问给解决了。

3.2 文本型特征转化为数值型特征

首先我们需要知道文本型特征有哪些值,有几种不同的值。可以用value_counts()、unique()、nunique()查看。

看下图可以看到缺失值在python中的地位,虽然按正常情况来说,我处理过应该是没有缺失值了才对。这个后面得查找一下原因。

接着就是进行类别变量的转换了。

转换成我们想要的值:

一种是使用replace替换掉,一种是使用map进行映射。还有一种是使用sklearn.preprocessing的LabelEncoder。这看起来是一种高大上的方法,标签编码。

train['Sex_num'] = train['Sex'].replace(['male', 'female','nan'],[1, 2, 3])
train['Sex_num'] = train['Sex'].map({'male':1, 'female': 2, 'nan': 3})

以上的LabelEncoder的使用方法和我百度到的有些许差异,但是结果显示目的达到了。这是我这篇文章遗留的第三个问题了,这个方法为什么需要这么写,网上的方法和它差异很大的原因是什么。

转换成one-hot模式:

本来以为这一篇终于要完了,真的是写了很久很久很久很久很久呀。

还有一道附加题,可是我很困。

从纯文本Name特征里提取出Titles的特征(所谓的Titles就是Mr,Miss,Mrs等)

df['Title'] = df.Name.str.extract('([A-Za-z]+)\.', expand=False)

这个正则表达式我也没看太懂,/(ㄒoㄒ)/~~ 明天要百度的东西好多呀。

今天先到此为止。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值