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

人工智能之数据分析 Pandas

第六章 数据清洗


文章目录

  • [人工智能之数据分析 Pandas](#人工智能之数据分析 Pandas)
  • 前言
  • [🧹 一、为什么需要数据清洗?](#🧹 一、为什么需要数据清洗?)
  • [🔍 二、数据概览:清洗前的第一步](#🔍 二、数据概览:清洗前的第一步)
  • [🚫 三、处理缺失值(Missing Values)](#🚫 三、处理缺失值(Missing Values))
    • [1. 识别缺失值](#1. 识别缺失值)
    • [2. 处理策略与方法](#2. 处理策略与方法)
      • [✅ 删除缺失](#✅ 删除缺失)
      • [✅ 填充缺失](#✅ 填充缺失)
      • [✅ 插值(适用于连续变量)](#✅ 插值(适用于连续变量))
  • [🔄 四、处理重复值(Duplicates)](#🔄 四、处理重复值(Duplicates))
    • [1. 检测重复](#1. 检测重复)
    • [2. 删除重复](#2. 删除重复)
  • [⚠️ 五、处理异常值(Outliers)](#⚠️ 五、处理异常值(Outliers))
    • [1. 检测方法](#1. 检测方法)
      • [IQR 方法示例:](#IQR 方法示例:)
    • [2. 处理策略](#2. 处理策略)
  • [🧩 六、数据类型修正](#🧩 六、数据类型修正)
  • [📏 七、格式标准化与单位统一](#📏 七、格式标准化与单位统一)
    • [1. 字符串清洗(使用 `.str` 访问器)](#1. 字符串清洗(使用 .str 访问器))
    • [2. 单位统一](#2. 单位统一)
  • [🗂️ 八、列与行的结构调整](#🗂️ 八、列与行的结构调整)
    • [1. 重命名列](#1. 重命名列)
    • [2. 删除无用列](#2. 删除无用列)
    • [3. 重排列顺序](#3. 重排列顺序)
    • [4. 行过滤(基于业务规则)](#4. 行过滤(基于业务规则))
  • [🧪 九、清洗后验证](#🧪 九、清洗后验证)
  • [🧰 十、高级技巧与工具推荐](#🧰 十、高级技巧与工具推荐)
  • [✅ 总结:数据清洗 Checklist](#✅ 总结:数据清洗 Checklist)
  • 后续
  • 资料关注

前言

数据清洗(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,后续会逐步更新。

资料关注

公众号:咚咚王

gitee:https://gitee.com/wy18585051844/ai_learning

《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》

相关推荐
geneculture2 小时前
融合全部讨论精华的融智学认知与实践总览图:掌握在复杂世界中锚定自我、有效行动、并参与塑造近未来的元能力
大数据·人工智能·数据挖掘·信息科学·融智学的重要应用·信智序位·全球软件定位系统
永霖光电_UVLED2 小时前
安森美与英诺赛科将合作推进氮化镓(GaN)功率器件的量产应用
人工智能·神经网络·生成对抗网络
Dev7z2 小时前
基于深度学习的脑肿瘤自动诊断和分析系统的研究与实现(Web界面+数据集+训练代码)
人工智能·深度学习
珠海西格电力2 小时前
零碳园区数字感知基础架构规划:IoT 设备布点与传输管网衔接设计
大数据·运维·人工智能·物联网·智慧城市·能源
AI即插即用2 小时前
即插即用系列 | WACV 2024 D-LKA:超越 Transformer?D-LKA Net 如何用可变形大核卷积刷新医学图像分割
图像处理·人工智能·深度学习·目标检测·计算机视觉·视觉检测·transformer
草莓熊Lotso2 小时前
《算法闯关指南:动态规划算法--斐波拉契数列模型》--04.解码方法
c++·人工智能·算法·动态规划
狂放不羁霸2 小时前
电子科技大学2025年机器学习期末考试回忆
人工智能·机器学习
多恩Stone3 小时前
【3DV 进阶-9】Hunyuan3D2.1 中的 MoE
人工智能·pytorch·python·算法·aigc
B站计算机毕业设计之家3 小时前
大数据项目:基于python电商平台用户行为数据分析可视化系统 电商订单数据分析 Django框架 Echarts可视化 大数据技术(建议收藏)
大数据·python·机器学习·数据分析·django·电商·用户分析