Pandas 数据清洗(最佳实践)

Pandas 数据清洗:从混乱到整洁的实战指南

在数据驱动的时代,我们每天都在与数据打交道。但真实世界中的数据,往往像一团乱麻——缺失值、重复项、格式不一、异常值……这些都让分析变得举步维艰。这时候,Pandas 就成了我们最可靠的助手。Pandas 不仅能高效处理结构化数据,更擅长把一团糟的数据“理顺”。今天,我们就来一起深入学习 Pandas 数据清洗 的核心技巧,让你的数据分析之路更加顺畅。


什么是 Pandas 数据清洗?

想象一下,你从一个网站导出了用户行为日志,结果发现有些用户的“年龄”字段是“未知”,有些是“25岁”,有些是“25”,还有些干脆是空的。这种数据我们称之为“脏数据”。而 Pandas 数据清洗,就是通过一系列操作,将这些不一致、不完整、不规范的数据,转化为干净、统一、可用的格式。

Pandas 提供了丰富的函数和方法,让我们可以轻松完成缺失值处理、重复数据删除、格式标准化、异常值识别等任务。掌握这些技巧,就等于掌握了数据质量的“金钥匙”。


检查数据:先看清“病灶”

在动手清洗之前,必须先“望闻问切”。我们得先了解数据的“健康状况”。

import pandas as pd

df = pd.read_csv('user_data.csv')

print(df.head())

print(df.info())

print(df.describe())

代码注释

  • df.head() 显示前 5 行数据,快速预览内容。
  • df.info() 提供每列的数据类型(如 int64、object)和非空值数量,帮助我们发现缺失。
  • df.describe() 对数值列生成均值、标准差、最小最大值等统计信息,是识别异常值的重要依据。

💡 小贴士:df.info() 是你每次加载数据后的第一道检查,它能快速告诉你“哪些列可能有缺失值”。


处理缺失值:别让“空”成为分析的绊脚石

缺失值(Missing Values)是数据清洗中最常见的问题。常见的表示方式有 NoneNaN、空字符串 '' 等。它们会让后续的计算出错或产生误导。

识别缺失值

print(df.isnull().sum())

print(df.isnull().mean() * 100)

代码注释

  • df.isnull() 返回布尔值矩阵,True 表示该位置是缺失值。
  • .sum() 统计每列中 True 的数量,即缺失值个数。
  • .mean() * 100 计算每列缺失值占比,帮助判断是否需要处理。

常见处理策略

1. 删除含缺失值的行(适用于缺失少且不重要)

df_cleaned = df.dropna()

df_cleaned = df.dropna(how='all')

代码注释

  • dropna() 默认删除任意一个值缺失的行。
  • how='all' 表示只有当整行全是缺失值时才删除,避免误删有效数据。

2. 填充缺失值(更常用)

df['age'].fillna(0, inplace=True)

df['age'].fillna(df['age'].mean(), inplace=True)

df['gender'].fillna(df['gender'].mode()[0], inplace=True)

df['sales'].fillna(method='ffill', inplace=True)

df['sales'].fillna(method='bfill', inplace=True)

代码注释

  • fillna() 是最核心的填充方法。
  • inplace=True 表示直接修改原数据,避免重新赋值。
  • method='ffill' 是“前向填充”,适合时间序列中偶尔缺失的值。

📌 建议:对于数值型数据,用均值或中位数填充;对于分类数据,用众数;对于时间序列,优先考虑前后填充。


去除重复数据:让每一行都独一无二

重复数据会严重影响统计结果。比如,一个用户在日志中被记录了两次,就会被误认为是两个独立用户。

print(df.duplicated().sum())

print(df[df.duplicated()])

df_cleaned = df.drop_duplicates()

代码注释

  • duplicated() 返回布尔序列,True 表示该行是重复的。
  • drop_duplicates() 默认保留第一次出现的重复项,也可通过 keep='last' 保留最后一次。
  • 可指定列进行去重,如 drop_duplicates(subset=['user_id']),仅根据用户 ID 去重。

✅ 小技巧:在数据清洗流程中,去重通常是“检查 → 删除”的一步,建议放在缺失值处理之后。


标准化数据格式:让数据“整齐划一”

数据格式不一致是另一个常见问题。比如“出生日期”字段可能有 “1990-01-01”、“1990/01/01”、“01-01-1990” 等多种格式。

df['birth_date'] = pd.to_datetime(df['birth_date'], errors='coerce')

print(df['birth_date'].isnull().sum())  # 查看转换失败的数量

代码注释

  • pd.to_datetime() 可自动识别多种日期格式。
  • errors='coerce' 是安全选项,避免因格式错误导致程序崩溃。

字符串清洗:统一大小写与去除空格

df['gender'] = df['gender'].str.upper()

df['name'] = df['name'].str.strip()

df['name'] = df['name'].str.replace(r'\s+', ' ', regex=True)

代码注释

  • .str.upper() 将字符串全部转为大写。
  • .str.strip() 去除首尾空格。
  • .str.replace(r'\s+', ' ', regex=True) 使用正则表达式将多个连续空白字符替换为一个空格。

识别与处理异常值:别让“ outliers”误导你

异常值(Outliers)是明显偏离正常范围的数据点。比如,一个“年龄”是 200 岁,明显不合理。

方法一:使用统计学方法(Z-Score)

from scipy import stats

z_scores = stats.zscore(df['age'])

outliers = df[abs(z_scores) > 3]

print(outliers)

代码注释

  • Z-Score 表示数据点与均值的偏离程度(单位:标准差)。
  • 通常认为 |Z| > 3 的数据为异常值。

方法二:使用四分位距(IQR)

Q1 = df['age'].quantile(0.25)
Q3 = df['age'].quantile(0.75)
IQR = Q3 - Q1

lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR

outliers = df[(df['age'] < lower_bound) | (df['age'] > upper_bound)]
print(outliers)

代码注释

  • IQR 法更稳健,不依赖正态分布假设。
  • 通常将低于 Q1 - 1.5×IQR 或高于 Q3 + 1.5×IQR 的值视为异常。

保存清洗后的数据:让成果“落地”

清洗完成后,别忘了保存结果,以便后续分析使用。

df_cleaned.to_csv('cleaned_user_data.csv', index=False)

代码注释

  • index=False 是好习惯,避免在 CSV 中多出一列“0,1,2…”的索引。
  • 你也可以保存为 Excel:to_excel('cleaned_data.xlsx', index=False)

总结:Pandas 数据清洗的核心流程

在实际项目中,Pandas 数据清洗 通常遵循以下流程:

  1. 加载数据 → 2. 检查缺失与重复 → 3. 处理缺失值 → 4. 去除重复项 → 5. 标准化格式 → 6. 识别异常值 → 7. 保存干净数据

这个流程就像“数据体检”——每一步都不可跳过。只有把“病灶”清除干净,后续的分析、建模、可视化才能真正发挥作用。

记住:数据质量决定分析质量。花时间做好清洗,远比花时间调模型更值。

现在,你已经掌握了 Pandas 数据清洗 的核心技能。下次面对一团乱麻的数据时,别慌,打开 Jupyter Notebook,一步一步来,你也能把它变成清晰、可靠、可用的分析资产。