【回顾&引言】前面一章的内容大家可以感觉到我们主要是对基础知识做一个梳理,让大家了解数据分析的一些操作,主要做了数据的各个角度的观察。那么在这里,我们主要是做数据分析的流程性学习,主要是包括了数据清洗以及数据的特征处理,数据重构以及数据可视化。这些内容是为数据分析最后的建模和模型评价做一个铺垫。
开始之前,导入numpy、pandas包和数据
#加载所需的库
import numpy as np
import pandas as pd
#加载数据train.csv
df = pd.read_csv('train.csv')
df.head(3)
2 第二章:数据清洗及特征处理
我们拿到的数据通常是不干净的,所谓的不干净,就是数据中有缺失值,有一些异常点等,需要经过一定的处理才能继续做后面的分析或建模,所以拿到数据的第一步是进行数据清洗,本章我们将学习缺失值、重复值、字符串和数据转换等操作,将数据清洗成可以分析或建模的亚子。
2.1 缺失值观察与处理
我们拿到的数据经常会有很多缺失值,比如我们可以看到Cabin列存在NaN,那其他列还有没有缺失值,这些缺失值要怎么处理呢
2.1.1 任务一:缺失值观察
(1) 请查看每个特征缺失值个数
(2) 请查看Age, Cabin, Embarked列的数据
以上方式都有多种方式,所以大家多多益善
#写入代码 哪个特征有缺失,发现Age,Cabin和Embarked属性下显示是True,说明这些属性下是有缺失的
nullfea = df.isnull().any()
print(nullfea)
#写入代码 查看特征缺失值的个数,发现Age有177个缺失值,Cabin为687个,Embarked为2个
nullnum = df.isnull().sum()
print(nullnum)
#写入代码 应用df.info()也可以看那些属性有缺失
df.info()
#查看Age, Cabin, Embarked列,并列出前5行
df[['Age','Cabin','Embarked']].head()
2.1.2 任务二:对缺失值进行处理
(1)处理缺失值一般有几种思路
(2) 请尝试对Age列的数据的缺失值进行处理
(3) 请尝试使用不同的方法直接对整张表的缺失值进行处理
#处理缺失值的一般思路:
#提醒:可使用的函数有--->dropna函数与fillna函数,其中第一个函数是把具有缺失值的列或者行删除,第二个函数是把要填入的内容补入缺失值,可以补平均值、中位数等。
df1 = df.fillna({'Age':0})
#用 fillna填充,df本身并没有变,只是产生出一个副本,因此我们把它定义为df1
#写入代码
df.loc[df['Age'].isnull(),'Age'] = 0
df.isnull().sum()
# 也可以用loc函数,这也相当于对前面命令的复习,因为loc函数显示的是行,那也就意味着对于Age这一列的所有行,如果里面有空的就都替换为0
#写入代码 用第一个方法对整张表的缺失值进行填充,但是注意这个是产生一个副本df1,但是由于上面我们用了loc函数进行填充,所以现在的df已经变成Age没有空值了
df1 = df.fillna(0)
df1.isnull().sum()
【思考1】dropna和fillna有哪些参数,分别如何使用呢?
【思考】检索空缺值用np.nan,None以及.isnull()哪个更好,这是为什么?如果其中某个方式无法找到缺失值,原因又是为什么?
【参考】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.2 重复值观察与处理
由于这样那样的原因,数据中会不会存在重复值呢,如果存在要怎样处理呢
2.2.1 任务一:请查看数据中的重复值
#写入代码 发现没有重复行
df1[df1.duplicated()]
2.2.2 任务二:对重复值进行处理
(1)重复值有哪些处理方式呢?
(2)处理我们数据的重复值
方法多多益善
#重复值有哪些处理方式:利用drop_duplicates()删除重复行
df1.drop_duplicates()
df1.count()
2.2.3 任务三:将前面清洗的数据保存为csv格式
#写入代码
df1.to_csv('new_train.csv')
2.3 特征观察与处理
我们对特征进行一下观察,可以把特征大概分为两大类:
数值型特征:Survived ,Pclass, Age ,SibSp, Parch, Fare,其中Survived, Pclass为离散型数值特征,Age,SibSp, Parch, Fare为连续型数值特征
文本型特征:Name, Sex, Cabin,Embarked, Ticket,其中Sex, Cabin, Embarked, Ticket为类别型文本特征,数值型特征一般可以直接用于模型的训练,但有时候为了模型的稳定性及鲁棒性会对连续变量进行离散化。文本型特征往往需要转换成数值型特征才能用于建模分析。
2.3.1 任务一:对年龄进行分箱(离散化)处理
(1) 分箱操作是什么?
(2) 将连续变量Age平均分箱成5个年龄段,并分别用类别变量12345表示
(3) 将连续变量Age划分为[0,5) [5,15) [15,30) [30,50) [50,80)五个年龄段,并分别用类别变量12345表示
(4) 将连续变量Age按10% 30% 50% 70% 90%五个年龄段,并用分类变量12345表示
(5) 将上面的获得的数据分别进行保存,保存为csv格式
分箱操作是什么:
答:分箱操作就是将连续数据转换为分类对应物的过程。⽐如将连续的年龄数据划分为:青年,中年,老年,这些是对应的模糊概念。这个好处是可以将异常值的影响降到最低,因为异常值只会进入到一个分组里面,对整体的数据分析影响有限,我们可以用pd.cut()
#写入代码
df1['Agegroup'] = pd.cut(df1['Age'],5,labels = list('12345'))
df1['Agegroup']
#接下来用直方图来画一下统计结果
from matplotlib import pyplot as plt
plt.hist(df1['Age'])
df1
#写入代码 分成的5个区间为左闭右开区间,因此加入right = False,在这里,我们也可以将之前Agegroup的1,2,3,4,5替换为这5个区间,
df1['Agegroup']=pd.cut(df1['Age'],[0,5,15,30,50,80],right = False,labels = list('12345'))
df1.head(10)
#写入代码 用pd.qcut()对数据进行百分比分段 这里没怎么听懂 细节上再看看,这里没有实现
df1['Agegand']=pd.qcut(df1['Age'],[0,0.1,0.3,0.5,0.7,0.9],labels=[1,2,3,4,5])
df
【参考】https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.cut.html
【参考】https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.qcut.html
2.3.2 任务二:对文本变量进行转换
(1) 查看文本变量名及种类
(2) 将文本变量Sex, Cabin ,Embarked用数值变量12345表示 (没怎么看懂)
(3) 将文本变量Sex, Cabin, Embarked用one-hot编码表示 (没怎么看懂)
#写入代码 使用value_counts()来查看,也可以用unique()
df1['Sex'].value_counts()
df1['Sex'].unique()
df1['Sex'].replace(['male','female'],[1,2],inplace = True)
df1.head()
这里inplace = Ture 表示replace直接作用于数据本身,如果是false则产生的是一个副本
2.3.3 任务三:从纯文本Name特征里提取出Titles的特征(所谓的Titles就是Mr,Miss,Mrs等)
这边我们需要把Name的特征中的Mrs/Mr/Miss这些拿出来,因此我们观察这些特征后面都直接跟着点符号,因此我们采用正则表达式进行识别。其中A-Za-z表示大写字母和小写字母。
如果不是很理解正则表达式的使用,建议看下该参考链接:55分钟学会正则表达式 - 知乎 (zhihu.com) 这里是参考网上资料https://zhuanlan.zhihu.com/p/541616897
#写入代码
df1['Title'] = df1.Name.str.extract('([A-Za-z]+)\.')
df1