查看原文
其他

Python 教学 | Pandas 缺失值与重复值的处理方法

分享技巧 数据Seminar 2023-08-12
 目录前言一、缺失值都有哪些二、如何处理缺失值    1.缺失值的识别    2.缺失值的处理方式
三、重复值的处理    1.检测重复值    2.删除重复值总结Python教程全文共5480个字,阅读约需14分钟,欢迎指正!

前言

数据清洗是数据分析和数据建模过程中重要步骤,关系到数据的质量,而数据的质量又关系到数据分析或建模的结果,为了避免出现 “Garbage In, Garbage Out” 现象,在进行几乎任何数据分析之前,都有必要进行数据清洗,而缺失值和重复值则是最常出现的数据问题。除了以上这些,我们在使用社科类数据,或者转换、处理数据时难免也会遇到不“干净”的数据,所以本期文章我们就来向大家介绍使用 Pandas 处理数据缺失值和重复值的方法。

一、缺失值都有哪些

在 Excel 表中,没有内容的单元格可以被认为是一个缺失值。而在 Python 中,任何对象都是一个数据,包括空值,但与 Excel 表不同的是,在 Python 中存在不止一种空值,下面我们通过下表简单认识一下 Python 中以及 Pandas 中的空值(缺失值)。

空值在 Python 中的表示
NaNnumpy.nan / numpy.NaN,由于导入numpy库时常常起别名为 “np”,所以实际使用时为 np.nannp.NaN
NoneNone,Python 自带的空值
NA /<NA>   pandas.NA,由于导入pandas库时常常起别名为 “pd”,所以实际使用时为 pd.NA
NaTpandas.NaT,时间类型空值,可表示为 pd.NaT
  1. NaN,“Not a Number” 的缩写,它是一种特殊的数据类型,用于表示缺失或无效的数值。它是 Numpy库中的常量,可以表示为 numpy.nan,和 Python 中的浮点数一样,numpy.nan 的类型也是float。由于 Pandas 是基于 Numpy 库开发的,所以 Pandas 中空值也就使用 numpy.nan 来表示。Pandas 读取表格数据时,会默认将表格中的空值转为 numpy.nan,如下图所示。
  1. None 是 Python 语言自带的一个空值,由于 Pandas 中默认的空值是 NaN,所以空值 None 很少出现,但是在读取 pdf 表格等跨第三方库转换、处理表格时,表中的空值一般会表示且显示为 None。
  2. NA 是 Pandas 库中的用于表示空值的对象,表示为 pd.NA。与 NaN 对象不同的是,pd.NA 的类型不是 float,一般不会影响同一个字段中的其他数值。
  3. 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()函数来删除缺失值,既可以用来删除行数据,也可以用来删除列数据,该函数常用的参数如下表所示。

参数名称可用的值描述
axis0 或 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()函数大致相同,核心参数都是subsetkeep,这里就不再列表说明了。与duplicated()函数不同的是,drop_duplicates()函数的作用不仅仅是检测重复值,而是将被检测出来的重复行删除。下面我们通过两个例子来学习一下如何使用它。

【场景1】删除数据中的重复行,保留其中一项

# 删除数据中的重复行,保留其中一项
data_test.drop_duplicates(keep='first')

【场景2】删除数据中的重复行,若发现重复行,则全部删除。

# 删除数据中的重复行,若发现重复行,则全部删除。
data_test.drop_duplicates(keep=False)

总结

在基础的数据清洗中,缺失值处理和重复值处理是最基本的技能,本期文章对缺失值和重复值的处理做了系统的介绍,其中重点介绍了如何填充缺失值以及如何删除重复值。下期文章我们将继续向大家介绍 Pandas 中其他的数据处理操作。

Python教程



星标⭐我们不迷路!想要文章及时到,文末“在看”少不了!

点击搜索你感兴趣的内容吧

往期推荐

Python 教学 | Pandas 妙不可言的条件数据筛选

Python 教学 | Pandas 数据索引与数据选取

Python 教学 | 数据处理必备工具之 Pandas(数据的读取与导出)

Python 教学 | 数据处理必备工具之 Pandas(基础篇)

Python 教学 | 数据处理必备工具之 Pandas(数据的读取与导出)




数据Seminar




这里是大数据、分析技术与学术研究的三叉路口


文 | 《社科领域大数据治理实务手册》


    欢迎扫描👇二维码添加关注    

点击下方“阅读全文”了解更多

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存