Python 教学 | Pandas 缺失值与重复值的处理方法
三、重复值的处理 1.检测重复值 2.删除重复值总结Python教程全文共5480个字,阅读约需14分钟,欢迎指正!
前言
数据清洗是数据分析和数据建模过程中重要步骤,关系到数据的质量,而数据的质量又关系到数据分析或建模的结果,为了避免出现 “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 |
NaN,“Not a Number” 的缩写,它是一种特殊的数据类型,用于表示缺失或无效的数值。它是 Numpy库中的常量,可以表示为 numpy.nan,和 Python 中的浮点数一样,numpy.nan 的类型也是 float
。由于 Pandas 是基于 Numpy 库开发的,所以 Pandas 中空值也就使用 numpy.nan 来表示。Pandas 读取表格数据时,会默认将表格中的空值转为 numpy.nan,如下图所示。
None 是 Python 语言自带的一个空值,由于 Pandas 中默认的空值是 NaN,所以空值 None 很少出现,但是在读取 pdf 表格等跨第三方库转换、处理表格时,表中的空值一般会表示且显示为 None。 NA 是 Pandas 库中的用于表示空值的对象,表示为 pd.NA。与 NaN 对象不同的是,pd.NA 的类型不是 float,一般不会影响同一个字段中的其他数值。 NaT,“Not a Time” 的缩写,表示时间戳中的缺失值。如果表格数据中的一列是日期类型,那么使用 Pandas 读取后,该列的缺失值会被表示为 pd.NaT。
二、如何处理缺失值
先使用 pandas 读取演示用的数据。
import numpy as np
import pandas as pd
data = pd.read_excel('./工业企业数据15条.xlsx')
data
1. 缺失值的识别
要处理缺失值,首先要查看数据中缺失值的分布情况,在 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 中不是空值
2. 缺失值的处理方法
(1)缺失值填充
缺失值的处理方法需要根据缺失值出现的原因,数据的用途来决定。很多时候缺失值的出现是正常的,比如企业数据中某企业缺失注吊销时间,这说明该企业可能处于存续状态(本就没有注吊销时间),那么此时不对“缺失值”做任何操作就是最好的处理方式。
在一些机器学习领域的数据预处理中,当部分“特征”(即指标)缺失时,这一条数据的其他特征仍然是有价值的,所以我们可以根据实际情况对这部分缺失的数据做填充操作,常见的填充方法有均值填充、中位数填充以及一些插值填充(主要针对内容为数值的特征)。在 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('')
(2)缺失值删除
当一条数据缺失关键信息,或者缺失值过多时,那么这条数据存在的价值就不高了,此时可以选择将这些数据删除。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
1. 检测重复值
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)]
使用上述代码得到了存在重复的所有数据行。
2. 删除重复值
与处理缺失值一样,重复值的处理方法也要根据实际情况而定,尤其是删除重复值时,是保留其中一行还是全部删除。Pandas 中删除重复值主要使用drop_duplicates()
函数,该函数与检测重复值的duplicated()
函数大致相同,核心参数都是subset
与keep
,这里就不再列表说明了。与duplicated()
函数不同的是,drop_duplicates()
函数的作用不仅仅是检测重复值,而是将被检测出来的重复行删除。下面我们通过两个例子来学习一下如何使用它。
【场景1】删除数据中的重复行,保留其中一项
# 删除数据中的重复行,保留其中一项
data_test.drop_duplicates(keep='first')
【场景2】删除数据中的重复行,若发现重复行,则全部删除。
# 删除数据中的重复行,若发现重复行,则全部删除。
data_test.drop_duplicates(keep=False)
总结
在基础的数据清洗中,缺失值处理和重复值处理是最基本的技能,本期文章对缺失值和重复值的处理做了系统的介绍,其中重点介绍了如何填充缺失值以及如何删除重复值。下期文章我们将继续向大家介绍 Pandas 中其他的数据处理操作。
Python教程
学习 Python 第一步——环境安装与配置 Python 基本数据类型 Python 字符串操作(上) Python 字符串操作(下) Python 变量与基本运算 组合数据类型-列表 组合数据类型-集合(内含实例) 组合数据类型 - 字典&元组 Python 中的分支结构(判断语句) Python 中的循环结构(上) Python 中的循环结构(下) Python教学 | Python函数的定义与调用 Python教学 | Python 内置函数 Python教学 | 最常用的标准库之一 —— os Python 教学 | “小白”友好型正则表达式教学(一) Python 教学 | “小白”友好型正则表达式教学(二) Python 教学 | “小白”友好型正则表达式教学(三) Python 教学 | 数据处理必备工具之 Pandas(基础篇) Python 教学 | 数据处理必备工具之 Pandas(数据的读取与导出) Python 教学 | Pandas 数据索引与数据选取 Python 教学 | Pandas 妙不可言的条件数据筛选 本期
星标⭐我们不迷路!想要文章及时到,文末“在看”少不了!
点击搜索你感兴趣的内容吧
往期推荐
数据Seminar
这里是大数据、分析技术与学术研究的三叉路口
文 | 《社科领域大数据治理实务手册》
欢迎扫描👇二维码添加关注