趋近智
识别数据集中缺失数据的准确位置是数据准备的基础。不完整的数据会阻碍模型训练,导致错误或有偏见的结果。幸运的是,Pandas库提供了有效的工具来定位这些缺失的条目。
Pandas主要使用特殊的浮点值 NaN (Not a Number,非数值) 来表示数值数组中的缺失数据。对于 object 数据类型(通常包含字符串)的列,Pandas可能使用 None 或 NaN。了解这种标准表示是识别缺失值的第一步。
考虑一个简单的DataFrame:
import pandas as pd
import numpy as np
data = {'col_a': [1, 2, np.nan, 4, 5],
'col_b': [np.nan, 'x', 'y', 'z', 'x'],
'col_c': [True, False, True, np.nan, False],
'col_d': [10.1, 20.2, 30.3, np.nan, 50.5]}
df = pd.DataFrame(data)
print(df)
# 输出:
# col_a col_b col_c col_d
# 0 1.0 NaN True 10.1
# 1 2.0 x False 20.2
# 2 NaN y True 30.3
# 3 4.0 z NaN NaN
# 4 5.0 x False 50.5
isnull() 和 isna() 检测缺失值Pandas提供了两个基本相同的方法,isnull() 和 isna(),用于检查缺失值。两者都返回一个与原始DataFrame形状相同的布尔型DataFrame,其中 True 表示缺失值 (NaN 或 None),False 表示存在值。
# 检查缺失值
missing_mask = df.isnull()
print(missing_mask)
# 输出:
# col_a col_b col_c col_d
# 0 False True False False
# 1 False False False False
# 2 True False False False
# 3 False False True True
# 4 False False False False
# isna() 产生相同结果
# missing_mask_alt = df.isna()
# print(missing_mask_alt)
反之,notnull() 和 notna() 方法返回相反的布尔掩码,标识数据所在的位置。
# 检查存在的值
present_mask = df.notnull()
print(present_mask)
# 输出:
# col_a col_b col_c col_d
# 0 True False True True
# 1 True True True True
# 2 False True True True
# 3 True True False False
# 4 True True True True
虽然布尔掩码很有用,但我们通常需要聚合统计。由于在数值上下文 (context)中 True 等于 1,False 等于 0,因此我们可以在 isnull() 之后链式调用 .sum() 方法来计算每列的缺失值数量。
# 计算每列的缺失值数量
missing_counts = df.isnull().sum()
print(missing_counts)
# 输出:
# col_a 1
# col_b 1
# col_c 1
# col_d 1
# dtype: int64
为了了解缺失数据的比例,您可以将计数除以总行数(DataFrame的长度):
# 计算每列缺失值的百分比
missing_percentage = (df.isnull().sum() / len(df)) * 100
print(missing_percentage)
# 输出:
# col_a 20.0
# col_b 20.0
# col_c 20.0
# col_d 20.0
# dtype: float64
要获取整个DataFrame中的缺失值总数,您可以对结果进行两次求和:
# 计算DataFrame中的总缺失值
total_missing = df.isnull().sum().sum()
print(f"总缺失值:{total_missing}")
# 输出:
# Total missing values: 4
您还可以通过在 sum() 方法中指定 axis=1 来计算每行的缺失值:df.isnull().sum(axis=1)。这有助于识别特别稀疏的行。
可视化通常能提供比原始数字更直观的缺失数据模式理解。一个常用方法是使用由 isnull() 生成的布尔掩码的热力图。Matplotlib 或 Seaborn 等库通常用于此目的。另一个有效的可视化是显示每个特征缺失值数量或百分比的条形图。
下面是使用Plotly生成一个汇总缺失值计数的条形图的方法:
import plotly.express as px
# 假设 missing_counts Series 来自上一步
fig = px.bar(x=missing_counts.index, y=missing_counts.values,
labels={'x':'特征', 'y':'缺失值数量'},
title="每个特征的缺失值数量")
fig.update_layout(xaxis_tickangle=-45, title_x=0.5)
# 若要显示图表(在支持Plotly的notebook或环境中):
# fig.show()
# 若要在网页内容中包含,可以导出JSON表示:
print(fig.to_json(pretty=False))
示例DataFrame中每列缺失条目数量的条形图。
有时,缺失数据不以 NaN 或 None 编码。数据集可能使用占位符字符串,如 "?"、"Unknown"、"N/A",或不太可能出现的数值,如 999 或 -1 来表示缺失条目。这些需要明确处理。
使用Pandas加载数据时(例如,使用 pd.read_csv),您可以使用 na_values 参数 (parameter)指定这些自定义标记 (token):
# 示例:假设 'data.csv' 使用 '?' 和 'N/A' 表示缺失值
# df = pd.read_csv('data.csv', na_values=['?', 'N/A'])
如果数据已加载,您可以使用 .replace() 方法将这些占位符转换为 np.nan,使得 isnull() 能够正确检测它们:
# 假设 df_dirty 在 'col_b' 列中包含 '?' 而不是 NaN
df_dirty = pd.DataFrame({
'col_a': [1, 2, np.nan],
'col_b': [10, '?', 30]
})
print("替换前:")
print(df_dirty)
print("\n替换前缺失值计数:")
print(df_dirty.isnull().sum())
# 将 '?' 替换为 NaN
df_clean = df_dirty.replace('?', np.nan)
print("\n替换后:")
print(df_clean)
print("\n替换后缺失值计数:")
print(df_clean.isnull().sum())
# 输出:
# 替换前:
# col_a col_b
# 0 1.0 10
# 1 2.0 ?
# 2 NaN 30
#
# 替换前缺失值计数:
# col_a 1
# col_b 0 # '?' 尚未被识别为缺失值
# dtype: int64
#
# 替换后:
# col_a col_b
# 0 1.0 10.0
# 1 2.0 NaN
# 2 NaN 30.0
#
# 替换后缺失值计数:
# col_a 1
# col_b 1 # '?' 现在被正确识别为 NaN
# dtype: int64
准确识别所有缺失值,无论是标准还是非标准的,都是必要的初始步骤。一旦识别出来,接下来可以了解数据为何缺失并选择合适的处理方法,这些都是本章后续部分的主题。
这部分内容有帮助吗?
© 2026 ApX Machine LearningAI伦理与透明度•