赞
踩
目录
数据清洗是数据分析和数据建模过程中重要步骤,关系到数据的质量,而数据的质量又关系到数据分析或建模的结果,为了避免出现 “Garbage In, Garbage Out” 现象,在进行几乎任何数据分析之前,都有必要进行数据清洗,而缺失值和重复值则是最常出现的数据问题。除了以上这些,我们在使用社科类数据,或者转换、处理数据时难免也会遇到不“干净”的数据,所以本期文章我们就来向大家介绍使用 Pandas 处理数据缺失值和重复值的方法。
在 Excel 表中,没有内容的单元格可以被认为是一个缺失值。而在 Python 中,任何对象都是一个数据,包括空值,但与 Excel 表不同的是,在 Python 中存在不止一种空值,下面我们通过下表简单认识一下 Python 中以及 Pandas 中的空值(缺失值)。
空值 | 在 Python 中的表示 |
---|---|
NaN | numpy.nan / numpy.NaN,由于导入numpy库时常常起别名为 “np”,所以实际使用时为 np.nan或np.NaN |
None | None,Python 自带的空值 |
NA /<NA> | pandas.NA,由于导入pandas库时常常起别名为 “pd”,所以实际使用时为 pd.NA |
NaT | pandas.NaT,时间类型空值,可表示为 pd.NaT |
float
。由于 Pandas 是基于 Numpy 库开发的,所以 Pandas 中空值也就使用 numpy.nan 来表示。Pandas 读取表格数据时,会默认将表格中的空值转为 numpy.nan,如下图所示。
None 是 Python 语言自带的一个空值,由于 Pandas 中默认的空值是 NaN,所以空值 None 很少出现,但是在读取 pdf 表格等跨第三方库转换、处理表格时,表中的空值一般会表示且显示为 None。
先使用 pandas 读取演示用的数据。
- import numpy as np
- import pandas as pd
- data = pd.read_excel('./工业企业数据15条.xlsx')
- data
要处理缺失值,首先要查看数据中缺失值的分布情况,在 Pandas 中,可以使用一行代码查看表中每一列中缺失值的数量或比例。
- ## 查看每一列缺失值的数量
- data.isna().sum()
- ## 查看每一列缺失值的占比
- data.isna().mean()
注意,如果需要在循环中处理数据,不要使用比较的方式来判断一个值是不是缺失值,因为 Pandas 中默认的缺失值 np.nan 与任何值(包括它本身)相比较得到的都是 False,即 np.nan 不等于任何值。想要判断一个值是不是空值,可以使用专门的函数,Pandas 中的 isna()
函数和notna()
函数可以用来判断一个对象是不是空值。
- ## pd.isna() 函数,若传入的值是空值就返回 False,否则返回 True
- print(pd.isna(1993)) # False
- print(pd.isna(np.nan)) # True
-
- ## pd.notna() 函数,若传入的值是空值就返回 True,否则返回 False
- print(pd.notna('')) # True
- print(pd.notna(None)) # False , 注意:空字符、空格符等在 Python 中不是空值
缺失值的处理方法需要根据缺失值出现的原因,数据的用途来决定。很多时候缺失值的出现是正常的,比如企业数据中某企业缺失注吊销时间,这说明该企业可能处于存续状态(本就没有注吊销时间),那么此时不对“缺失值”做任何操作就是最好的处理方式。
在一些机器学习领域的数据预处理中,当部分“特征”(即指标)缺失时,这一条数据的其他特征仍然是有价值的,所以我们可以根据实际情况对这部分缺失的数据做填充操作,常见的填充方法有均值填充、中位数填充以及一些插值填充(主要针对内容为数值的特征)。在 Pandas 中,主要使用fillna()
函数来填充缺失值,它可以将表中的缺失值替换为我们指定的数据值,既可以一次性对整张表做填充操作,也可以对某一列做填充操作。下面是fillna()
函数的使用方法。
- ## 注意,在没有设置参数 inplace=True 或重新赋值的情况下,
- ## fillna() 函数不会直接修改原始数据,而是返回一个处理后的新对象
-
- ## 均值填充法填充“资产总计(万元)”字段,只做演示用,这样做实际上没有任何意义
- value_mean = data['资产总计(万元)'].mean() # 得出“资产总计(万元)”字段的平均值
- # 下面填充缺失值,这里是重新赋值操作,将会修改原数据
- data['资产总计(万元)'] = data['资产总计(万元)'].fillna(value_mean)
- data # 查看填充后的数据
如果希望使用中位数进行填充,那么上述代码中的.mean()
替换为.median()
即可。如果希望使用其它值进行填充,只需将要填充的值传入fillna()
函数即可。
注意:这里的缺失值填充方法针对的是机器学习训练数据,实际应用中不建议直接套用在统计数据上,要根据缺失值出现的原因、数据的用途等“对症下药”。
除了在数据预处理中需要填充缺失值,很多时候为了保持数据一致性也要对数据进行填充。举个例子,我们想要从上图所示的数据中筛选出“企业名称”中包含关键词“北京”的数据,我们使用下面的数据筛选代码,但是却得到了一个报错。
data[data['企业名称'].str.contains('北京')]
这个报错大概意思就是企业名称字段中缺失值 NA 或 NaN 无法参与字符串的“包含”运算,所以为了不让空值 NaN 影响字符运算,我们常用的方法就是使用空字符''
去填充缺失值,这样做既可以保证数据类型一致性,而且空字符虽然不是严格意义上的空值,但是具有空值的含义,因此在许多数据处理操作之前都需要将表中的空值填充为空字符,代码如下。
- ## 将一个字段中的空值填充为空字符
- # 方法 1
- data['企业名称'].fillna('', inplace=True)
- # 方法 2
- data['企业名称'] = data['企业名称'].fillna('')
-
- ## 将整张表中的缺失值填充为空字符
- # 方法 1
- data.fillna('', inplace=True)
- # 方法 2
- data = data.fillna('')
当一条数据缺失关键信息,或者缺失值过多时,那么这条数据存在的价值就不高了,此时可以选择将这些数据删除。Pandas 一般使用dropna()
函数来删除缺失值,既可以用来删除行数据,也可以用来删除列数据,该函数常用的参数如下表所示。
参数名称 | 可用的值 | 描述 |
---|---|---|
axis | 0 或 1 | 默认值为 0,为 0 时,删除的是数据行;为 1 时删除的是数据列 |
how | 'any' 或 'all' | 默认值为 'any' ,表示只要行/列中存在缺失值,那么整行/列就会被删除;参数值为 'all' 时,只有当行/列中所有值都是空值的时候才会被删除。 |
subset | 字段名称列表 | 根据哪些字段做删除操作,默认是全部字段 |
thresh | 数字 | 数据行/列不被删除时,该行/列中非缺失值个数的最小值。举个例子,当参数thresh=4,那么一行数据中含有至少 4 个非缺失值时才不会被删除。指定thresh参数后,how 参数将会失效 |
下面我们就来介绍一下如何使用 Pandas 中的dropna()
函数删除缺失值。
【场景1】删除含有缺失值的数据行
- ## 先重新读取演示数据
- data = pd.read_excel('./工业企业数据15条.xlsx')
-
- # 删除含有缺失值的数据行
- data.dropna(axis=0, how='any') # 这两个参数都可以省略不写,因为参数值都是默认值
【场景2】删除企业名称
、成立年份
和行业门类名称
这三个字段中存在缺失值的数据行
- # 删除企业名称、成立年份和行业门类名称这三个字段中存在缺失值的数据行
- # 前两个参数都可以省略不写,因为都是默认值
- data.dropna(axis=0, how='any', subset=['企业名称', '成立年份', '行业门类名称'])
【场景3】删除缺失值数量大于 3 个的数据列
- # 删除缺失值数量大于 3 个的数据列
- data.dropna(axis=1, thresh=data.shape[1]-3)
先从前面的数据中抽取几行数据,作为演示处理重复值得数据
- data_test = data.loc[[0,0,1,1,2], :]
- data_test
Pandas 中用于检测重复值的函数是 duplicated()
,只能用来检测重复的数据行,该函数的主要参数和作用如下表所示。
参数名称 | 参数取值 | 描述 |
---|---|---|
subset | 字段名称列表 | 根据哪些字段做重复值检测操作,默认是全部字段 |
keep | 'first'、'last' 或 False | 默认值为'first',为'first'时,如果存在多行(大于等于2)数据完全一样,那么只有所有重复行的第一行不会被标记为重复行;为'last'时则只有最后一行不会被标记为重复行;当为False时,所有重复行都会被标记为重复行。 |
duplicated()
函数的返回值是一个 Series,重复的行会被标记为 True, 非重复行会被标记为 False。查找所有重复行的代码和结果如下。
- # 查找所有重复的数据行,首次出现的数据行不计入其中
- data_test.duplicated(keep='first')
而想要直接得到重复的数据行,则需要借助数据筛选功能,将上述代码视作数据筛选的条件表达式即可,代码如下(注意,修改了参数)。
- # 找出所有重复的数据行,并返回重复数据
- data_test[data_test.duplicated(keep=False)]
使用上述代码得到了存在重复的所有数据行。
与处理缺失值一样,重复值的处理方法也要根据实际情况而定,尤其是删除重复值时,是保留其中一行还是全部删除。Pandas 中删除重复值主要使用drop_duplicates()
函数,该函数与检测重复值的duplicated()
函数大致相同,核心参数都是subset
与keep
,这里就不再列表说明了。与duplicated()
函数不同的是,drop_duplicates()
函数的作用不仅仅是检测重复值,而是将被检测出来的重复行删除。下面我们通过两个例子来学习一下如何使用它。
【场景1】删除数据中的重复行,保留其中一项
- # 删除数据中的重复行,保留其中一项
- data_test.drop_duplicates(keep='first')
【场景2】删除数据中的重复行,若发现重复行,则全部删除。
- # 删除数据中的重复行,若发现重复行,则全部删除。
- data_test.drop_duplicates(keep=False)
在基础的数据清洗中,缺失值处理和重复值处理是最基本的技能,本期文章对缺失值和重复值的处理做了系统的介绍,其中重点介绍了如何填充缺失值以及如何删除重复值。下期文章我们将继续向大家介绍 Pandas 中其他的数据处理操作。
本期
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。