首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >人工智能之数据分析 Pandas:第六章 数据清洗

人工智能之数据分析 Pandas:第六章 数据清洗

原创
作者头像
咚咚王
发布2025-12-06 20:24:08
发布2025-12-06 20:24:08
3640
举报

人工智能之数据分析 Pandas

第六章 数据清洗


前言

数据清洗(Data Cleaning) 是数据分析中最关键、最耗时的环节,通常占整个分析流程的 60%~80% 时间。Pandas 提供了强大而灵活的工具来高效完成这项任务。

本文将从 缺失值、重复值、异常值、数据类型、格式标准化、文本清洗、列/行操作 等维度,系统、详细、实战化地介绍 Pandas 数据清洗的核心方法与技巧。


🧹 一、为什么需要数据清洗?

真实世界的数据往往存在以下问题:

  • 缺失值(NaN, NULL, 空字符串)
  • 重复记录
  • 错误或异常值(如年龄为 -5、工资为 1 亿)
  • 数据类型不一致(数字存为字符串)
  • 格式混乱(日期格式多样、单位不统一)
  • 噪声数据(乱码、特殊符号)
  • 列名/值命名不规范

目标:将“脏数据”转化为结构清晰、类型正确、逻辑合理、可直接用于分析的干净数据。


🔍 二、数据概览:清洗前的第一步

在动手清洗前,先全面了解数据:

代码语言:python
复制
import pandas as pd
import numpy as np

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

# 基本信息
print(df.shape)               # (行数, 列数)
print(df.dtypes)              # 每列类型
print(df.info())              # 非空计数 + 内存
print(df.describe())          # 数值列统计
print(df.head())              # 查看前几行

# 缺失值分布
print(df.isnull().sum())      # 每列缺失数量
print((df.isnull().sum() / len(df)) * 100)  # 缺失百分比

# 唯一值 & 频次(用于发现异常类别)
for col in df.select_dtypes(include='object').columns:
    print(f"{col}:\n{df[col].value_counts(dropna=False)}\n")

🚫 三、处理缺失值(Missing Values)

1. 识别缺失值

Pandas 将以下视为缺失:

  • np.nan
  • None
  • pd.NaT(时间缺失)
  • 读取时通过 na_values 指定的值(如 'N/A', '-'
代码语言:python
复制
df.isnull()        # 返回布尔 DataFrame
df.isna()          # 同 isnull()

2. 处理策略与方法

策略

方法

适用场景

删除

dropna()

缺失比例高、无法填补

填充

fillna()

有合理填充值

插值

interpolate()

时间序列或有序数据

标记

新增列标识是否缺失

保留缺失信息用于建模

✅ 删除缺失

代码语言:python
复制
# 删除含任意缺失的行(默认)
df_clean = df.dropna()

# 删除所有值都缺失的行
df.dropna(how='all')

# 删除某列缺失的行
df.dropna(subset=['age'])

# 删除缺失超过阈值的列
df.dropna(axis=1, thresh=len(df)*0.8)  # 保留至少 80% 非空的列

✅ 填充缺失

代码语言:python
复制
# 填充固定值
df.fillna(0)                     # 数值填 0
df.fillna('Unknown')             # 分类填 'Unknown'

# 填充统计量
df['salary'].fillna(df['salary'].mean(), inplace=True)
df['city'].fillna(df['city'].mode()[0], inplace=True)  # 众数

# 前向/后向填充(时间序列常用)
df.fillna(method='ffill')   # forward fill
df.fillna(method='bfill')   # backward fill

# 按组填充(更合理!)
df['salary'] = df.groupby('department')['salary'].transform(
    lambda x: x.fillna(x.mean())
)

✅ 插值(适用于连续变量)

代码语言:python
复制
df['temperature'].interpolate(method='linear')  # 线性插值
df['price'].interpolate(method='time')          # 按时间索引插值

💡 建议:避免简单全局均值填充,优先考虑分组填充模型预测填充(如 KNNImputer)。


🔄 四、处理重复值(Duplicates)

1. 检测重复

代码语言:python
复制
# 全行重复
df.duplicated().sum()           # 重复行数
df[df.duplicated()]             # 查看重复行(保留首次出现)

# 指定列重复
df.duplicated(subset=['user_id'])

2. 删除重复

代码语言:python
复制
# 保留首次出现(默认)
df.drop_duplicates(inplace=True)

# 保留最后一次
df.drop_duplicates(keep='last', inplace=True)

# 基于特定列去重
df.drop_duplicates(subset=['email'], keep='first')

⚠️ 注意:去重前确认业务逻辑——有些“重复”可能是合法的(如多次购买记录)。


⚠️ 五、处理异常值(Outliers)

异常值 ≠ 错误值,需结合业务判断。

1. 检测方法

  • 统计法:3σ 原则(正态分布)、IQR(四分位距)
  • 可视化:箱线图、散点图
  • 领域规则:年龄 > 150?工资 < 0?

IQR 方法示例:

代码语言:python
复制
def detect_outliers_iqr(series):
    Q1 = series.quantile(0.25)
    Q3 = series.quantile(0.75)
    IQR = Q3 - Q1
    lower = Q1 - 1.5 * IQR
    upper = Q3 + 1.5 * IQR
    return (series < lower) | (series > upper)

outliers = detect_outliers_iqr(df['salary'])
print(df[outliers])

2. 处理策略

策略

方法

删除

df[~outliers]

截断(Winsorize)

用上下限值替换

转换

对数变换 np.log(x)

保留

若为真实极端值(如富豪收入)

截断示例:

代码语言:python
复制
upper_limit = df['salary'].quantile(0.95)
df['salary'] = np.where(df['salary'] > upper_limit, upper_limit, df['salary'])

🧩 六、数据类型修正

错误的数据类型会导致计算错误或内存浪费。

1. 常见问题

  • 数字被读成 object(因含非数字字符)
  • 日期未解析为 datetime
  • 整数含缺失 → 变为 float64

2. 修正方法

转换数值类型

代码语言:python
复制
# 强制转数字,错误变 NaN
df['price'] = pd.to_numeric(df['price'], errors='coerce')

# 指定整数类型(支持缺失)
df['user_id'] = df['user_id'].astype('Int64')  # 注意大写 I

解析日期

代码语言:python
复制
df['date'] = pd.to_datetime(df['date'], errors='coerce', format='%Y-%m-%d')
# 自动推断格式(慢但灵活)
df['date'] = pd.to_datetime(df['date'], infer_datetime_format=True)

优化内存(分类变量)

代码语言:python
复制
# 将低基数字符串转为 category
df['gender'] = df['gender'].astype('category')
df['city'] = df['city'].astype('category')

# 查看内存节省
df.info(memory_usage='deep')

📏 七、格式标准化与单位统一

1. 字符串清洗(使用 .str 访问器)

代码语言:python
复制
# 去除空格
df['name'] = df['name'].str.strip()

# 大小写统一
df['email'] = df['email'].str.lower()

# 替换非法字符
df['phone'] = df['phone'].str.replace(r'\D', '', regex=True)  # 只留数字

# 提取模式
df['area_code'] = df['phone'].str[:3]

# 拆分列
df[['first', 'last']] = df['full_name'].str.split(' ', expand=True)

2. 单位统一

代码语言:python
复制
# 工资单位统一为“元”
df['salary'] = np.where(
    df['salary_unit'] == '千元',
    df['salary'] * 1000,
    df['salary']
)

🗂️ 八、列与行的结构调整

1. 重命名列

代码语言:python
复制
df.rename(columns={'old_name': 'new_name'}, inplace=True)

# 批量标准化列名
df.columns = df.columns.str.lower().str.replace(' ', '_')

2. 删除无用列

代码语言:python
复制
df.drop(['temp_col', 'id_backup'], axis=1, inplace=True)

3. 重排列顺序

代码语言:python
复制
df = df[['id', 'name', 'age', 'salary']]  # 指定顺序

4. 行过滤(基于业务规则)

代码语言:python
复制
# 年龄合理范围
df = df[(df['age'] >= 0) & (df['age'] <= 120)]

# 邮箱格式校验
df = df[df['email'].str.contains('@', na=False)]

🧪 九、清洗后验证

清洗不是一次性任务,需验证结果:

代码语言:python
复制
# 再次检查缺失
assert df.isnull().sum().sum() == 0, "仍有缺失值!"

# 检查类型
assert df['age'].dtype == 'int64'
assert df['date'].dtype == 'datetime64[ns]'

# 检查唯一性
assert df['user_id'].is_unique, "user_id 不唯一!"

# 保存清洗后数据
df.to_csv('clean_data.csv', index=False)

🧰 十、高级技巧与工具推荐

场景

工具/方法

自动检测数据质量问题

pandas-profiling(现 ydata-profiling

交互式清洗

OpenRefine(外部工具)

复杂文本清洗

正则表达式 + str.extract()

批量清洗多文件

glob + 循环

可复现清洗流程

封装为函数或使用 sklearnTransformer

示例:封装清洗函数

代码语言:python
复制
def clean_employee_data(df):
    df = df.copy()
    df.columns = df.columns.str.lower().str.replace(' ', '_')
    df['salary'] = pd.to_numeric(df['salary'], errors='coerce')
    df['age'] = pd.to_numeric(df['age'], errors='coerce')
    df = df[(df['age'] >= 18) & (df['age'] <= 65)]
    df['email'] = df['email'].str.lower().str.strip()
    df = df.drop_duplicates(subset=['email'])
    return df

clean_df = clean_employee_data(raw_df)

✅ 总结:数据清洗 Checklist

步骤

操作

1️⃣ 概览

shape, info(), isnull().sum()

2️⃣ 缺失值

删除 / 填充 / 插值

3️⃣ 重复值

drop_duplicates()

4️⃣ 异常值

检测 + 截断/删除

5️⃣ 类型修正

to_numeric, to_datetime, astype('category')

6️⃣ 格式标准化

.str 方法清洗文本

7️⃣ 结构调整

重命名、删列、重排序

8️⃣ 验证

断言检查 + 保存


💡 记住“垃圾进,垃圾出”(Garbage In, Garbage Out) 再强大的模型也无法弥补脏数据带来的偏差。

后续

python过渡项目部分代码已经上传至gitee,后续会逐步更新。

资料关注

公众号:咚咚王

《Python编程:从入门到实践》

《利用Python进行数据分析》

《算法导论中文第三版》

《概率论与数理统计(第四版) (盛骤) 》

《程序员的数学》

《线性代数应该这样学第3版》

《微积分和数学分析引论》

《(西瓜书)周志华-机器学习》

《TensorFlow机器学习实战指南》

《Sklearn与TensorFlow机器学习实用指南》

《模式识别(第四版)》

《深度学习 deep learning》伊恩·古德费洛著 花书

《Python深度学习第二版(中文版)【纯文本】 (登封大数据 (Francois Choliet)) (Z-Library)》

《深入浅出神经网络与深度学习+(迈克尔·尼尔森(Michael+Nielsen)》

《自然语言处理综论 第2版》

《Natural-Language-Processing-with-PyTorch》

《计算机视觉-算法与应用(中文版)》

《Learning OpenCV 4》

《AIGC:智能创作时代》杜雨+&+张孜铭

《AIGC原理与实践:零基础学大语言模型、扩散模型和多模态模型》

《从零构建大语言模型(中文版)》

《实战AI大模型》

《AI 3.0》

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 人工智能之数据分析 Pandas
  • 前言
  • 🧹 一、为什么需要数据清洗?
  • 🔍 二、数据概览:清洗前的第一步
  • 🚫 三、处理缺失值(Missing Values)
    • 1. 识别缺失值
    • 2. 处理策略与方法
      • ✅ 删除缺失
      • ✅ 填充缺失
      • ✅ 插值(适用于连续变量)
  • 🔄 四、处理重复值(Duplicates)
    • 1. 检测重复
    • 2. 删除重复
  • ⚠️ 五、处理异常值(Outliers)
    • 1. 检测方法
      • IQR 方法示例:
    • 2. 处理策略
      • 截断示例:
  • 🧩 六、数据类型修正
    • 1. 常见问题
    • 2. 修正方法
      • 转换数值类型
      • 解析日期
      • 优化内存(分类变量)
  • 📏 七、格式标准化与单位统一
    • 1. 字符串清洗(使用 .str 访问器)
    • 2. 单位统一
  • 🗂️ 八、列与行的结构调整
    • 1. 重命名列
    • 2. 删除无用列
    • 3. 重排列顺序
    • 4. 行过滤(基于业务规则)
  • 🧪 九、清洗后验证
  • 🧰 十、高级技巧与工具推荐
    • 示例:封装清洗函数
  • ✅ 总结:数据清洗 Checklist
  • 后续
  • 资料关注
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档