我们拿到的数据通常是不干净的,所谓的不干净,就是数据中有缺失值,有一些异常点等,需要经过一定的处理才能继续做后面的分析或建模,所以拿到数据的第一步是进行数据清洗,本章我们将学习缺失值、重复值、字符串和数据转换等操作,将数据清洗成可以分析或建模的样子。

1 缺失值观察与处理

1.1 缺失值观察

查看每个特征的缺失值个数有多种方法,以下将展示三种方法。

#数据导入
import pandas as pd
import numpy as np
train=pd.read_csv("train.csv")
#方法1 info()函数
train.info()
#方法2 count()函数
train.count()
#方法3 统计空值个数
train.isnull().sum()

以上三种查看缺失值个数的方法中,法1和法2返回的均是非缺失值的个数,法3返回的是缺失值的个数。
以下展示方法3的返回结果:

NLP 数据预处理中数据清洗包括哪些_缺失值

从返回的结果可以得到,Age缺失值个数为177个;Cabin缺失值个数为687个;Embarked缺失值个数为2个。

1.2 缺失值处理

常见的缺失值处理有以下几种方式:
1、直接删除该特征:此方法针对存在大量缺失值,且该特征对结果影响不大的情况。
2、针对数值型的特征可采用均值插补,即在缺失值的位置填充该特征的均值。均值插补中又包括了分层均值插补和回归均值插补。
3、针对非数值型的特征可采用中位数插补,即在缺失值的位置填充该特征的中位数。
4、使用最可能的值填充缺失值:可以用回归、使用贝叶斯形式化方法的基于推理的工具或决策树归纳确定。

对Age列的数据的缺失值进行处理

#处理方法1:将Age列的缺失值进行删除
train.dropna(subset=['Age'],inplace=True)
train.isnull().sum()
#处理方法2:用均值填充Age列的缺失值
train['Age'].fillna(train['Age'].mean(),inplace=True)
train.isnull().sum()

【思考1】:dropna和fillna有哪些参数,分别如何使用呢?
1、dataframe.dropna(axis=0, how=‘any’, thresh=None, subset=None, inplace=False)
其中axis=0为默认对缺失值的行进行处理,axis=1为对缺失值的列进行处理;
how默认为any,即有缺失值就删除整行或整列;how为all时,整行或列都为缺失值时才进行删除;
thresh为保留含有n个非nan值的行;
subset可以指定需要操作的列或行;
inplace默认为False,即不在原数据上进行操作,当inplace为True时,删除缺失值的操作直接在原数据上进行。
2、dataframe.fillna(value=None, method=None, axis=None, inplace=False, limit=None, downcast=None)
其中value为所要填充的数据,有’backfill’, ‘bfill’, ‘pad’, ‘ffill’,默认值为None;
method为填充的方式;
axis=0为默认对缺失值的行进行处理,axis=1为对缺失值的列进行处理;
inplace默认为False,即不在原数据上进行操作,当inplace为True时,删除缺失值的操作直接在原数据上进行。

1.3 对整个数据集的处理

原始数据集中,Age缺失值个数为177个;Cabin缺失值个数为687个;Embarked缺失值个数为2个。针对Age,使用中位数对缺失值进行填充;针对Cabin,缺失值率达到77.10%,笔者将该列进行删除;针对Embarked,缺失值仅为2个,笔者将使用众数进行填充,使用describe()函数观察后,S为出现最多的值,则使用S对两个缺失值进行填充。

#对数据集的缺失值进行处理
#处理Age缺失值
train['Age'].fillna(train['Age'].median(),inplace=True)
#处理Cabin缺失值
del train['Cabin']
#处理Embarked缺失值
train.replace(np.nan,'S',inplace=True)

2 重复值观察与处理

2.1 重复值观察

python中的.duplicated()可用来观察重复值。

#计算重复值个数
train.duplicated().sum()

得到的结果是泰坦尼克号数据集中的重复值为0。

2.2重复值的处理

重复值的处理方法为删除重复的行,仅保留一行。
python中使用.drop_duplicates()。

train=train.drop_duplicates()

3 特征值观察与处理

3.1 对年龄进行分箱(离散化)处理

分箱离散化是一种无监督的离散化方式,如通过使用等宽或等频分箱,然后用箱均值或中位数替换箱中的每个值,可以将属性值离散化。它对用户指定的箱个数很敏感,也容易受离群点的影响。

#将连续变量Age平均分箱成5个年龄段,并分别用类别变量12345表示
train['AgeBand']=pd.cut(train.Age,5,labels=[1,2,3,4,5])

#将连续变量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],right=False)

#将连续变量Age按10% 30% 50% 70% 90%五个年龄段,并用分类变量12345表示
train['AgeBand'] = pd.qcut(train.Age,[0,0.1,0.3,0.5,0.7,0.9],labels = [1,2,3,4,5])

3.2 对文本变量进行转化

#查看文本变量名及种类 .value_counts()或者.unique()函数
train.Sex.value_counts()
train.Embarked.value_counts()
#结果:
# male      577
# female    314
# Name: Sex, dtype: int64
# S    646
# C    168
# Q     77
# Name: Embarked, dtype: int64

#将文本变量Sex,Embarked用数值变量12345表示 replace函数
train['Sex_new'] = train['Sex'].replace(['female','male'],[1,2])
train['Embarked_new'] = train['Embarked'].replace(['S','C','Q'],[1,2,3])

#将文本变量Sex,Embarked用one-hot编码表示
#One-Hot 编码是分类变量作为二进制向量的表示,它将分类值映射到整数值,然后每个整数值被表示为二进制向量,除了整数的索引之外,它都是零值,它被标记为1。
Sex=pd.get_dummies(train['Sex'])
train=pd.concat([train,Sex],axis=1)
Embarked=pd.get_dummies(train['Embarked'])
train=pd.concat([train,Embarked],axis=1)
train.head()

其结果展示为:

NLP 数据预处理中数据清洗包括哪些_缺失值_02

3.3 从纯文本Name特征里提取出Titles的特征

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

提取结果:

NLP 数据预处理中数据清洗包括哪些_中位数_03