Pandas 缺失值的处理
1. 前言
通过前面几个小节的学习,我们掌握了 Pandas 解析数据和数据增删改查的基础操作,能有效对数据的量和内容进行处理,但我们在解析数据的时候经常会出现缺失值的情况,这些缺失数据的存在不仅影响数据的美观,还会影响到数据分析和挖掘的结果,那 Pandas 库中又是怎么解决缺失值这一问题的呢?
针对数据中的缺失值,Pandas 库提供了便捷的操作去检查缺失值,并对缺失值作出处理,本小节,我们将学习 Pandas 检测缺失值的方法,以及 Pandas 处理缺失值常见的两种方式。
2. 缺失值的检测
在学习进行缺失值处理之前,我们先来看一下什么是缺失值,为什么会出现缺失值?
缺失值 —— 是指粗糙数据中由于缺少信息而造成的数据的聚类、分组、删失或截断。它指的是现有数据集中某个或某些属性的值是不完全的。(来源:百度百科)
缺失值的出现是很正常的一种现象,首先我们要正视缺失值的存在,缺失值的出现一般来说有机械原因和人为原因,但在我们实际应用中,多说是我们人为的失误或错误的操作导致的缺失,缺失值的出现对于我们分析数据的过程不会产生过大的影响,但是对于数据分析的结果可能会产生致命的影响,影响数据的准确性和结果的可靠性。
在 Pandas 中,对于缺失值使用浮点值 NaN 进行表示,如下图我们将 Excel 数据文件中删除几个数据值,进行数据的解析:
然后我通过 Pandas 库进行数据的解析,可以看到数据缺失值的表示 NaN:
2.1 isnull () 函数
该函数用来检测缺失值,如果是缺失值 NaN 则数据返回的是 True,不是缺失值返回的是 False。
# 导入pandas包
import pandas as pd
data_path="C:/Users/13965/Documents/myFuture/IMOOC/pandasCourse-progress/data_source/第11小节/execl数据demo.xlsx"
# 解析数据
data = pd.read_excel(data_path)
print(data)
# --- 输出结果 ---
编程语言 推出时间 价格 主要创始人
0 java NaN 45.6 James Gosling
1 python 1991年 67.0 NaN
2 NaN 1972年 NaN Dennis MacAlistair Ritchie
3 js NaN NaN Brendan Eich
4 php 2012年 NaN Rasmus Lerdorf
5 C++ 1983年 75.0 Bjarne Stroustrup
# 检查是否是缺失值
data.isnull()
# --- 输出结果 ---
编程语言 推出时间 价格 主要创始人
0 False True False False
1 False False False True
2 True False True False
3 False True True False
4 False False True False
5 False False False False
输出解析:通过结果可以看到,是缺失值 NaN 的数据,在该函数检查后,都返回了 True,否则则是 False。
2.2 notnull () 函数
该函数也能检测缺失值,但是和 isnull () 函数相反,对于缺失值 NaN 的数据返回 False,否则为 True。
# data 是上面从 Excel 中解析出来的数据
# 检查是否不是缺失值
data.notnull()
# --- 输出结果 ---
编程语言 推出时间 价格 主要创始人
0 True False True True
1 True True True False
2 False True False True
3 True False False True
4 True True False True
5 True True True True
输出解析:通过结果可以看到,不是缺失值 NaN 的数据,在该函数检查后,都返回了 True,否则则是 False。
3. 缺失值的处理
Pandas 提供了便捷的方法去检测缺失值,当然他还提供了对应的函数去处理缺失值,这里我们将学习缺失值的两种处理方式,一种是过滤缺失值,也就对存在缺失值的行或者列,进行过滤操作;另一种是我们对缺失的数据进行填充处理。
3.1 dropna () 函数
该函数用于过滤含有缺失值的数据行或者列,操作之后会返回一个新的数据集,该函数提供了丰富的参数设置,下面列举了该函数常用的几个参数:
参数名 | 说明 |
---|---|
axis | 指定是行还是列的过滤( 0 指行,1 为列),默认 axis=0 |
how | 指定缺失值过滤的依据,含有缺失值就过滤(how=“any” 默认)还是全是全是缺失值才过滤(how=“all”) |
thresh | 指保留至少含有多少个非缺失值的行或列(参数值为整数) |
subset | 指定特定的行或者列进行缺失值过滤 |
下面我们将通过实际程序操作,学习每个参数的使用方式:
# 导入pandas包
import pandas as pd
data_path="C:/Users/13965/Documents/myFuture/IMOOC/pandasCourse-progress/data_source/第11小节/execl数据demo.xlsx"
# 解析数据
data = pd.read_excel(data_path)
print(data)
# --- 输出结果 ---
编程语言 推出时间 价格 主要创始人
0 java NaN 45.6 James Gosling
1 python 1991年 67.0 NaN
2 NaN 1972年 NaN Dennis MacAlistair Ritchie
3 js NaN NaN Brendan Eich
4 php 2012年 NaN Rasmus Lerdorf
5 C++ 1983年 75.0 Bjarne Stroustrup
###### dropna 过滤缺失值
# 1. axis=0 设置过滤行中有缺失值的数据
new_data= data.dropna(axis=0)
print(new_data)
# --- 输出结果 ---
编程语言 推出时间 价格 主要创始人
5 C++ 1983年 75.0 Bjarne Stroustrup
# 结果解析:可以看到所有含 NaN 的数据行都被过滤掉,只剩下一行数据
# 2. axis=1 设置过滤行列中缺失值的数据
new_data= data.dropna(axis=1)
print(new_data)
# --- 输出结果 ---
Empty DataFrame
Columns: []
Index: [0, 1, 2, 3, 4, 5]
# 结果解析:因为原数据中每一列都有 NaN 数据的存在,所以 axis=1 操作后,数据集为 Empty DataFrame
# 3. how="all" 设置所有值都为 NaN 的数据列才被过滤
new_data= data.dropna(axis=1,how="all")
print(new_data)
# --- 输出结果 ---
编程语言 推出时间 价格 主要创始人
0 java NaN 45.6 James Gosling
1 python 1991年 67.0 NaN
2 NaN 1972年 NaN Dennis MacAlistair Ritchie
3 js NaN NaN Brendan Eich
4 php 2012年 NaN Rasmus Lerdorf
5 C++ 1983年 75.0 Bjarne Stroustrup
# 结果解析:通过设置 how="all" 因为原数据不存在全为 NaN 的数据列,因此并没有进行数据的过滤,输出为原数据集
# 4. thresh=4 只保留含有4个及4个以上的非缺失值的数据
new_data= data.dropna(axis=1,thresh=4)
print(new_data)
# --- 输出结果 ---
编程语言 推出时间 主要创始人
0 java NaN James Gosling
1 python 1991年 NaN
2 NaN 1972年 Dennis MacAlistair Ritchie
3 js NaN Brendan Eich
4 php 2012年 Rasmus Lerdorf
5 C++ 1983年 Bjarne Stroustrup
# 结果解析:因为"价格"这一列只有3个非缺失值的数据,因此设置 thresh=4,会将该列过滤掉。
# 5. subset 指定要过滤的数据列
new_data= data.dropna(axis=0,subset=["价格","主要创始人"])
print(new_data)
# --- 输出结果 ---
编程语言 推出时间 价格 主要创始人
0 java NaN 45.6 James Gosling
5 C++ 1983年 75.0 Bjarne Stroustrup
# 结果解析:这里通过 subset 指定过滤"价格""主要创始人"列中存在 NaN 数据的行,通过结果可以看到,过滤掉了行索引为1,2,3,4的行。
3.2 fillna () 函数
该函数用于填充缺失值的操作,返回一个新的数据集,该函数提供了丰富的参数可供设置,下面列举了常用的几个参数:
参数名 | 说明 |
---|---|
value | 指定用什么值去填充 |
method | 填充的方式,ffill 用前一个非缺失值填充这个缺失值,bfill 用下一个非缺失值填充这个缺失值,None 默认的,指定一个缺失值去填充 |
axis | 修改填充的方向 ,默认是 axis=0 在列的方向填充 |
limit | 指定填充的个数,在某个方向如果存在多个连续的缺失值,指定填充的几个 |
下面通代码程序来看一个每个参数的具体使用方式:
# 导入pandas包
import pandas as pd
data_path="C:/Users/13965/Documents/myFuture/IMOOC/pandasCourse-progress/data_source/第11小节/execl数据demo.xlsx"
# 解析数据
data = pd.read_excel(data_path)
print(data)
# --- 输出结果 ---
编程语言 推出时间 价格 主要创始人
0 java NaN 45.6 James Gosling
1 python 1991年 67.0 NaN
2 NaN 1972年 NaN Dennis MacAlistair Ritchie
3 js NaN NaN Brendan Eich
4 php 2012年 NaN Rasmus Lerdorf
5 C++ 1983年 75.0 Bjarne Stroustrup
# 1. 直接设置 value 指定填充的内容
new_data= data.fillna("###")
print(new_data)
# --- 输出结果 ---
编程语言 推出时间 价格 主要创始人
0 java ### 45.6 James Gosling
1 python 1991年 67 ###
2 ### 1972年 ### Dennis MacAlistair Ritchie
3 js ### ### Brendan Eich
4 php 2012年 ### Rasmus Lerdorf
5 C++ 1983年 75 Bjarne Stroustrup
# 结果解析:通过设置填充的值为 ### ,可以看到原数据集中的缺失值都被填充了该字符
# 2. 设置 method 填充的方向
new_data= data.fillna(method="bfill")
print(new_data)
# --- 输出结果 ---
编程语言 推出时间 价格 主要创始人
0 java 1991年 45.6 James Gosling
1 python 1991年 67.0 Dennis MacAlistair Ritchie
2 js 1972年 75.0 Dennis MacAlistair Ritchie
3 js 2012年 75.0 Brendan Eich
4 php 2012年 75.0 Rasmus Lerdorf
5 C++ 1983年 75.0 Bjarne Stroustrup
# 结果解析:这里设置了填充的方式为 bfill ,默认的 axis=0 是在列上,表示用这一列的下一行的非缺失值填充这个缺失值,通过输出结果可看到,缺失值均被填上了内容,这里要注意一点,如果下一个数据为 NaN,则会继续往下找,直到找到一个非缺失值的数据来填充。
# 3. 设置 axis=1 在横向上进行填充
new_data= data.fillna(axis=1,method="bfill")
print(new_data)
# --- 输出结果 ---
编程语言 推出时间 价格 主要创始人
0 java 45.6 45.6 James Gosling
1 python 1991年 67 NaN
2 1972年 1972年 Dennis MacAlistair Ritchie Dennis MacAlistair Ritchie
3 js Brendan Eich Brendan Eich Brendan Eich
4 php 2012年 Rasmus Lerdorf Rasmus Lerdorf
5 C++ 1983年 75 Bjarne Stroustrup
# 结果解析:这里程序中设置了 axis 为横向,method 为 bfill ,通过输出结果可以看到为 NaN 的数据,用他后面的非缺失值进行了填充,如果他后面没有数据,则不进行填充,仍然为 NaN。
# 4. limit 指定出现连续的缺失值,填充的数量
new_data= data.fillna(axis=0,method="bfill",limit=2)
print(new_data)
# --- 输出结果 ---
编程语言 推出时间 价格 主要创始人
0 java 1991年 45.6 James Gosling
1 python 1991年 67.0 Dennis MacAlistair Ritchie
2 js 1972年 NaN Dennis MacAlistair Ritchie
3 js 2012年 75.0 Brendan Eich
4 php 2012年 75.0 Rasmus Lerdorf
5 C++ 1983年 75.0 Bjarne Stroustrup
# 结果解析:通过设置 limit=2 指定出现连续的缺失值只填充2个数据,这里可以看到在"价格"列中原数据出现的连续三个 NaN 这里按列的方向,只填充了两个数据。
3. 小结
本节课程我们主要学习了 Pandas 检测数据集中存在缺失值的方法,同时学习了 Pandas 对缺失值的过滤操作和填充缺失值的方法。本节课程的重点如下:
- isnull () 函数和 notnull () 函数对缺失值的检测操作和检测返回结果;
- dropna () 函数对缺失值的过滤操作,以及其中常用参数的设置方式;
- fillna () 函数对缺失值的填充操作,以及其中常用参数的设置方式。