3.4.2 缺失值的处理
在数据分析的过程中,缺失值(Missing Data)是一个常见且必须处理的重要问题。Python 中的 Pandas 库为我们提供了多种方法来处理缺失值,包括填充、删除和检查缺失值等功能。本文将介绍一些常见的处理缺失值的方法,并展示如何利用 Pandas 进行高效的缺失值操作。
1. 什么是缺失值?
缺失值是指数据集中缺少的数值,它通常以 None 或 np.nan 表示。
- None:是 Python 中的空对象,类型为
object,通常不参与计算,计算时可能会耗时较长。 - np.nan:是 Pandas 中表示缺失数据的标准值,类型为
float,可以参与计算,但会导致结果为空。
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randint(1, 10, (3, 4)))
df.loc[0, 1] = np.nan
df.loc[1, 2] = np.nan
df.loc[2, 3] = np.nan
print(df)
0 1 2 3
0 6.0 NaN 3.0 4.0
1 8.0 5.0 NaN 6.0
2 3.0 9.0 7.0 NaN
2. 处理缺失值的常用方法
2.1 使用 np.nansum() 忽略 NaN 值进行计算
在进行运算时,我们可以使用 np.nansum(),它会忽略掉 NaN 值进行计算:
np.nansum(df) # 可以通过np.nan* 忽略nan进行运算
2.2 使用 isnull() 和 notnull() 检查缺失值
我们可以使用 pd.isnull() 或 pd.notnull() 来检查 DataFrame 中的缺失值。
isnull():判断元素是否为缺失值(NaN)。notnull():判断元素是否不是缺失值。
print(pd.isnull(df)) # 判断各元素是否为 NaN
print(pd.notnull(df)) # 判断各元素是否不是 NaN
2.3 使用 all() 和 any() 判断列或行是否包含 NaN
all():当所有值都是 NaN 时返回True。any():只要有一个值是 NaN,就返回True。
print(pd.isnull(df).all()) # 检查每一列是否全部为 NaN
print(pd.isnull(df).any()) # 检查每一列是否有 NaN
print(pd.isnull(df).all(axis=1)) # 检查每一行是否全部为 NaN
print(pd.isnull(df).any(axis=1)) # 检查每一行是否有 NaN
2.4 过滤空值(NaN)
2.4.1 行过滤
我们可以通过布尔值过滤缺失值。如果一行中含有 NaN 值,则返回 True:
condition = pd.isnull(df).any(axis=1)
print(df[~condition]) # 筛选不包含 NaN 的行
2.4.2 列过滤
我们可以检查每一列是否包含 NaN 值,如果有则返回 True:
condition = pd.isnull(df).any()
print(df.loc[:, ~condition]) # 筛选不包含 NaN 的列
2.4.3 使用 dropna() 删除缺失值
dropna() 是一个非常方便的方法,可以直接删除包含缺失值的行或列。
# 默认删除包含空值的行
print(df.dropna())
# 删除包含空值的列
print(df.dropna(axis=1))
# 只要全是 NaN 才会删除
print(df.dropna(how='all'))
# 删除包含任何 NaN 值的行
print(df.dropna(how='any'))
# 使用 inplace=True,直接修改原 DataFrame
df.dropna(inplace=True)
print(df)
2.5 使用 fillna() 填充缺失值
fillna() 方法可以用来填充缺失值。我们可以指定填充的值,或者使用前后值进行填充。
- 填充指定值:通过
value参数指定一个值来填充缺失值。
df.fillna(value=100)
- 限制填充数量:使用
limit参数限制最多填充多少个 NaN 值。
df.fillna(value=66, limit=2) # 最多填充 2 个 NaN
- 使用前后值填充:
method='ffill':使用前一个值填充 NaN。method='bfill':使用后一个值填充 NaN。
df.fillna(method='ffill', limit=2) # 使用前一个非 NaN 值填充
df.fillna(method='backfill', limit=2) # 使用下一个非 NaN 值填充
- 使用
inplace=True修改原 DataFrame:
df.fillna(value=66, inplace=True) # 直接修改 df
3.4.3 重复数据处理
在数据分析中,清洗数据是非常重要的一部分,尤其是当你有重复的数据时。Pandas 提供了强大的方法来帮助我们识别和处理重复数据。本文将通过一个简单的示例来讲解如何在 Pandas 中查找和删除重复数据。
示例数据
import pandas as pd
data = {
"学号": ["2022000001", "2022000001", "2022000002", "2022000003"],
"姓名": ["zhangsan", "lisi", "wangwu", "zhaoliu"],
"性别": ["男", "男", "女", "女"]
}
df = pd.DataFrame(data)
print(df)
输出如下:
学号 姓名 性别
0 2022000001 zhangsan 男
1 2022000001 lisi 男
2 2022000002 wangwu 女
3 2022000003 zhaoliu 女
我们注意到,学号为 2022000001 的学生有重复的记录。这时候我们就需要处理重复数据,确保每个学生的学号只有一条记录。
- 判断重复数据
- 判断是否有重复值
首先,我们可以使用 duplicated() 方法来判断整个 DataFrame 是否有重复的记录。该方法会返回一个布尔型的 Series,True 表示该行是重复的,False 表示该行是唯一的。
df.duplicated()
2.针对某一列判断重复值
有时我们可能只关心某一列的重复数据,比如在本例中我们只关心学号(学号)是否有重复。在这种情况下,我们可以使用 duplicated(subset=["学号"]) 方法。
df.duplicated(subset=["学号"])
输出:
0 True
1 False
2 False
3 False
dtype: bool
可以看到,只有学号为 2022000001 的第一行被标记为重复。
- 保留重复项的特定行
有时候我们希望删除重复的行,但要保留某一行,比如保留重复项的第一条记录或最后一条记录。可以通过设置 keep 参数来实现。
- 保留第一行:使用
keep="first",默认行为。
df.duplicated(subset=["学号"], keep="first")
输出:
0 True
1 False
2 False
3 False
dtype: bool
- 保留最后一行:使用
keep="last"。
pythondf.duplicated(subset=["学号"], keep="last")
输出:
0 False
1 True
2 False
3 False
dtype: bool
- 不保留任何重复项
如果你想删除所有重复的行,可以使用 keep=False。这会标记所有重复的行。
df.duplicated(subset=["学号"], keep=False)
输出:
0 True
1 True
2 False
3 False
dtype: bool
- 删除重复的数据
一旦我们识别了重复的数据,就可以使用 drop_duplicates() 方法删除这些重复的行。drop_duplicates() 方法可以通过 subset 参数指定要检查重复的列,通过 keep 参数指定要保留的重复项。
- 删除重复行(保留第一条记录)
我们可以通过 keep="first" 保留第一次出现的记录,删除后续的重复记录:
df.drop_duplicates(subset=["学号"], keep="first", inplace=True)
print(df)
输出:
学号 姓名 性别
0 2022000001 zhangsan 男
2 2022000002 wangwu 女
3 2022000003 zhaoliu 女
- 删除重复行(保留最后一条记录)
如果我们希望保留最后一条记录,可以使用 keep="last":
df.drop_duplicates(subset=["学号"], keep="last", inplace=True)
print(df)
输出:
学号 姓名 性别
1 2022000001 lisi 男
2 2022000002 wangwu 女
3 2022000003 zhaoliu 女
- 删除所有重复行
如果我们希望删除所有重复的记录(即删除所有重复学号的行),可以使用 keep=False:
df.drop_duplicates(subset=["学号"], keep=False, inplace=True)
print(df)
输出:
学号 姓名 性别
2 2022000002 wangwu 女
3 2022000003 zhaoliu 女
3748

被折叠的 条评论
为什么被折叠?



