【转载】使用pandas进行数据清洗

使用pandas进行数据清洗

本文转载自:蓝鲸的网站分析笔记
html

原文连接:使用python进行数据清洗python

 

目录:git

 


 数据清洗是一项复杂且繁琐(kubi)的工做,同时也是整个数据分析过程当中最为重要的环节。有人说一个分析项目80%的时间都是在清洗数据,这听起来有些匪夷所思,但在实际的工做中确实如此。数据清洗的目的有两个,第一是经过清洗让数据可用。第二是让数据变的更适合进行后续的分析工做。换句话说就是有”脏”数据要洗,干净的数据也要洗。本篇文章将介绍几种简单的使用python进行数据清洗的方法。app

cleansing-big-data

开始以前仍是先在python中导入须要使用的库文件,而后进行数据读取,并建立名为loandata的数据表。这里为了更好的展现清洗的步骤和结果,咱们使用的是lendingclub公开数据中的一小部分。函数

1
2
3
import numpy as np
import pandas as pd
loandata=pd.DataFrame(pd.read_excel('loandata.xlsx'))

原始数据表

数据清洗的目的有两个,第一是经过清洗让脏数据变的可用。这也是咱们首先要解决的问题。不管是线下人工填写的手工表,仍是线上经过工具收集到的数据,又或者是CRM系统中导出的数据。不少数据源都有一些这样或者那样的问题,例如:数据中的重复值,异常值,空值,以及多余的空格和大小写错误的问题。下面咱们逐一进行处理。工具

数据表中的重复值

第一个要处理的问题是数据表中的重复值,pandas中有两个函数是专门用来处理重复值的,第一个是duplicated函数。Duplicated函数用来查找并显示数据表中的重复值。下面是使用这个函数对数据表进行重复值查找后的结果。网站

1
loandata.duplicated()

查看重复值
这里有两点须要说明:第一,数据表中两个条目间全部列的内容都相等时duplicated才会判断为重复值。(Duplicated也能够单独对某一列进行重复值判断)。第二,duplicated支持从前向后(first),和从后向前(last)两种重复值查找模式。默认是从前向后进行重复值的查找和判断。换句话说就是将后出现的相同条件判断为重复值。在前面的表格中索引为4的1311748和索引为1的条目相同。默认状况下后面的条目在重复值判断中显示为True。spa

Pandas中的drop_duplicates函数用来删除数据表中的重复值,判断标准和逻辑与duplicated函数同样。使用drop_duplicates函数后,python将返回一个只包含惟一值的数据表。下面是使用drop_duplicates函数后的结果。与原始数据相比减小了3行,仔细观察能够发现,drop_duplicates默认也是使用了first模式删除了索引为4的重复值,以及后面的另外两个重复值。3d

1
loandata.drop_duplicates()

删除重复值

数据表中的空值/缺失值

第二个要处理的问题是数据表中的空值,在python中空值被显示为NaN。在处理空值以前咱们先来检查下数据表中的空值数量。对于一个小的数据表,咱们能够人工查找,但对于较为庞大的数据表,就须要寻找一个更为方便快捷的方法了。首先,对关键字段进行空值查找。这里咱们分别选择了对loan_amnt字段和annual_inc字段查找空值。excel

Pandas中查找数据表中空值的函数有两个,一个是函数isnull,若是是空值就显示True。另外一个函数notnull正好相反,若是是空值就显示False。如下两个函数的使用方法以及经过isnull函数得到的空值数量。

1
loandata.isnull()
1
loandata.notnull()

经过isnull函数和value_counts函数分别得到了loan_amnt列和annual_inc列中的空值数据量。

计算特定列空值数量计算特定列空值数量1

对于空值有两种处理的方法,第一种是使用fillna函数对空值进行填充,能够选择填充0值或者其余任意值。第二种方法是使用dropna函数直接将包含空值的数据删除。

1
loandata.fillna(0)
1
loandata.dropna()

这里咱们选择对空值数据进行填充,首先处理loan_amnt列中的空值。经过totalpymnt字段和total_tec_int字段值相减计算出loan_amnt列中的近似值。由于这里除了利息之外还可能包括一些逾期费,手续费和罚息等,因此只能得到一个实际贷款金额近似值。因为贷款金额一般是一个整数,所以咱们在代码的最后对格式进行了转换。

1
loandata['loan_amnt']=loandata['loan_amnt'].fillna(loandata['total_pymnt']-loandata['total_rec_int']).astype(np.int64)

计算并填充loan_amnt列空值

对于annual_inc列,在原始数据表中没有可用的辅助列进行计算,所以咱们选择用现有数据的均值进行填充。这里能够看到贷款用户的收入均值为50060美金。使用这个值对annual_inc中的空值进行填充。

1
loandata['annual_inc']=loandata['annual_inc'].fillna(loandata['annual_inc'].mean())

填充annual_inc列空值

数据间的空格

第三个要处理的是数据中的空格。空格会影响咱们后续会数据的统计和计算。从下面的结果中就能够看出空格对于常规的数据统计形成的影响。

查看数据中的空格
咱们再对loan_status列进行频率统计时,因为空格的问题,相同的贷款状态被重复计算。形成统计结果不可用。所以,咱们须要解决字段中存在的空格问题。

1
loandata['loan_status'].value_counts()

查看列中的空格

去除数据中的空格
Python中去除空格的方法有三种,第一种是去除数据两边的空格,第二种是单独去除左边的空格,第三种是单独去除右边的空格。

1
loandata['term']=loandata['term'].map(str.strip)
1
loandata['term']=loandata['term'].map(str.lstrip)
1
loandata['term']=loandata['term'].map(str.rstrip)

这里咱们使用去除两边的空格来处理loan_status列中的空格。如下是具体的代码和去除空格后的结果。

去除左右两侧的空格

从新查看loan_status列中每种贷款状态的频率,以前空格形成的影响已经没有了,但这里还有个问题,就是大小写的问题。所以,咱们还须要对每种贷款状态的大小写进行统一化处理。这是咱们第四个要处理的问题。

查看去除空格后的数据

大小写转换

大小写转换的方法也有三种能够选择,分别为所有转换为大写,所有转换为小写,和转换为首字母大写。

1
loandata['term']=loandata['term'].map(str.upper)
1
loandata['term']=loandata['term'].map(str.lower)
1
loandata['term']=loandata['term'].map(str.title)

这里咱们将全部贷款状态转换为首字母大写模式,并再次进行频率统计。从下面的结果中能够看出,结果以及消除了空格和大小写字母混乱的影响。清晰的显示了贷款的三种状态出现的频率。

规范大小写后的数据

最后咱们还须要对数据表中关键字段的内容进行检查,确保关键字段中内容的统一。主要包括数据是否所有为字符,或数字。下面咱们对emp_length列进行检验,此列内容由数字和字符组成,若是只包括字符,说明可能存在问题。下面的代码中咱们检查该列是否所有为字符。答案所有为False。

1
loandata['emp_length'].apply(lambda x: x.isalpha())

检查字段内容
除此以外,还能检验该列的内容是否所有为字母或数字。或者是否所有为数字。

1
loandata['emp_length'].apply(lambda x: x. isalnum ())
1
loandata['emp_length'].apply(lambda x: x. isdigit ())

数据中的异常和极端值

第五个要处理的问题是数据中的异常值和极端值,发现异常值和极端值的方法是对数据进行描述性统计。使用describe函数能够生成描述统计结果。其中咱们主要关注最大值(max)和最小值(min)状况。

检查异常和极端值
下面是对数据表进行描述统计的结果,其中loan_amnt的最大值和最小值分别为100000美金和36美金,这不符合业务逻辑,所以能够判断为异常值。

1
loandata.describe().astype(np.int64).T

检查异常值和极端值

异常数据替换
对于异常值数据咱们这里选择使用replace函数对loan_amnt的异常值进行替换,这里替换值选择为loan_amnt的均值。下面是具体的代码和替换结果。

1
loandata.replace([100000,36],loandata['loan_amnt'].mean())

异常值替换为均值

数据清洗的第二个目的是让数据更加适合后续的分析工做。提早对数据进行预处理,后面的挖掘和分析工做会更加高效。这些预处理包括数据格式的处理,数据分组和对有价值信息的提取。下面咱们逐一来介绍这部分的操做过程和使用到的函数。

更改数据格式

第一步是更改和规范数据格式,所使用的函数是astype。下面是更改数据格式的代码。对loan_amnt列中的数据,因为贷款金额一般为整数,所以咱们数据格式改成int64。若是是利息字段,因为会有小数,所以一般设置为float64。

1
loandata['loan_amnt']=loandata['loan_amnt'].astype(np.int64)

在数据格式中还要特别注意日期型的数据。日期格式的数据须要使用to_datatime函数进行处理。下面是具体的代码和处理后的结果。

1
loandata['issue_d']=pd.to_datetime(loandata['issue_d'])

格式更改后能够经过dtypes函数来查看,下面显示了每一个字段的数据格式。

1
loandata.dtypes

查看更改后字段格式

数据分组

第二步是对数据进行分组处理,在数据表的open_acc字段记录了贷款用户的帐户数量,这里咱们能够根据帐户数量的多少对用户进行分级,5个帐户如下为A级,5-10个帐户为B级,依次类推。下面是具体的代码和处理结果。

1
2
3
bins = [0, 5, 10, 15, 20]
group_names = ['A', 'B', 'C', 'D']
loandata['categories'] = pd.cut(loandata['open_acc'], bins, labels=group_names)

首先设置了数据分组的依据,而后设置每组对应的名称。最后使用cut函数对数据进行分组并将分组后的名称添加到数据表中。

数据分组

数据分列

第四步是数据分列,这个操做和Excel中的分列功能很像,在原始数据表中grade列中包含了两个层级的用户等级信息,如今咱们经过数据分列将分级信息进行拆分。数据分列操做使用的是split函数,下面是具体的代码和分列后的结果。

1
grade_split = pd.DataFrame((x.split('-') for x in loandata.grade),index=loandata.index,columns=['grade','sub_grade'])

数据分列

完成数据分列操做后,使用merge函数将数据匹配会原始数据表,这个操做相似Excel中的Vlookup函数的功能。经过匹配原始数据表中包括了分列后的等级信息。如下是具体的代码和匹配后的结果。

1
loandata=pd.merge(loandata,grade_split,right_index=True, left_index=True)

数据分列后拼接

相关文章
相关标签/搜索