Skip to content

数据清洗是什么 ​

数据清洗是指发现并纠正数据中可识别的错误的过程,包括处理缺失值、重复值、异常值,统一数据格式,保证数据的一致性。

四类常见脏数据:

text
重复值处理 · 缺失值处理 · 异常值处理 · 异常格式处理

缺失值处理 ​

python
df.isnull()                 # 查看缺失值(每个位置是不是空,True/False)
df.isnull().sum()           # 看每列有几个缺失值(更常用)

df.dropna()                 # 删除缺失值所在【行】
df.dropna(axis=1)           # 删除缺失值所在【列】

df.fillna('--')             # 用指定值填充
df.ffill()                  # 用【上一行】的值填充
df.bfill()                  # 用【下一行】的值填充
方法作用
isnull()查看缺失值
dropna()删除缺失值所在行;加 axis=1 删列
fillna(值)填充缺失值
ffill()用上一行的值填充
bfill()用下一行的值填充

重复值处理 ​

python
df.duplicated()                          # 查看重复值(所有列都相同才算重复)
df.duplicated(subset=['订单号'])          # 只按指定列判断是否重复

df.drop_duplicates(subset=['订单号'])     # 删除重复值,默认保留第一条(keep='first')
df.drop_duplicates(subset=['订单号'], keep='last')   # 保留最后一条

NOTE

判断"重复"的标准由 subset 决定:订单数据通常按订单号去重,而不是要求整行一模一样。

异常值处理 ​

python
df[df['单价'] < 0]                       # 1. 查看异常值
df.drop(df[df['单价'] < 0].index)         # 2. 删除异常值(按索引删行)
df['单价'] = df['单价'].abs()             # 3. 修复异常值(取绝对值)

处理异常值有三条路:查看 → 删除 或 修复。负数单价很可能是录入时漏了负号,取绝对值比直接删更合适。

异常格式处理 ​

python
df['订单日期'] = df['订单日期'].str.replace('/', '-')   # 2025/06/01 → 2025-06-01

.str 是 Series 的"字符串方法入口",可以像操作单个字符串一样对整列做替换、切片、分割:df['类型'].str.split(',')、df['上映时间'].str[:4]。

相关 ​

练习题 ​

一、知识回顾(读完直接做下面的实践题) ​

  1. 数据清洗包括处理缺失值、重复值、异常值,以及统一数据格式、保证一致性
  2. 查看缺失值:df.isnull();看每列缺失数量:df.isnull().sum()
  3. 删除缺失值所在行:df.dropna();删除缺失值所在列要加参数 axis=1
  4. 用上一行的值填充缺失值用 df.ffill();用下一行用 df.bfill()
  5. 查看重复值:df.duplicated(),按指定列判断加参数 subset=[...]
  6. 删除重复值:df.drop_duplicates(subset=['订单号']);保留最后一条用 keep='last'
  7. 异常值三条路:用 df[条件] 查看、用 df.drop(索引) 删除、用 .abs() 修复
  8. 把整列的 / 替换成 -:df['订单日期'].str.replace('/', '-')

二、裸写题 ​

数据:data/sales.csv

  • - 提示(先自己想,实在想不出再点开)

    一级 · 思路:先量化问题规模,再决定怎么处理 二级 · 方法:df.isnull().sum() / df.duplicated(subset=['订单号']).sum()三级 · 骨架:duplicated 返回的是 True/False 序列,sum() 就是重复条数

    - 参考答案(做完再点开)

    python
    import pandas as pd
    
    df = pd.read_csv('data/sales.csv')
    
    # 2-1
    print(df.isnull().sum())
    print(df.duplicated(subset=['订单号']).sum())
  • - 提示(先自己想,实在想不出再点开)

    一级 · 思路:删除会少行,填充不会;填充时想清楚用什么值合理 二级 · 方法:df.dropna() / df.fillna('--') / df.ffill()三级 · 骨架:用 len(df) 前后对比行数

    - 参考答案(做完再点开)

    python
    # 2-2
    print(len(df))                      # 处理前行数
    print(len(df.dropna()))             # 删除缺失值后的行数
    print(len(df.fillna('--')))         # 填充后行数不变
    print(len(df.ffill()))              # 用上一行填充
  • - 提示(先自己想,实在想不出再点开)

    一级 · 思路:去重前先记录行数,去重后再看 二级 · 方法:df.drop_duplicates(subset=['订单号'])三级 · 骨架:keep='____' 是默认值(保留第一条)

    - 参考答案(做完再点开)

    python
    # 2-3
    before = len(df)
    df2 = df.drop_duplicates(subset=['订单号'], keep='first')
    print(before, '→', len(df2))
  • - 提示(先自己想,实在想不出再点开)

    一级 · 思路:定位异常 → 删;格式问题 → 整列字符串替换 二级 · 方法:df.drop(df[df['单价'] < 0].index) / .str.replace('/', '-')三级 · 骨架:负单价也可以用 .abs() 修复而不是删除,两种都试试

    - 参考答案(做完再点开)

    python
    # 2-4
    df3 = df.drop(df[df['单价'] < 0].index)          # 删除单价为负的行
    print(len(df), '→', len(df3))
    
    df['订单日期'] = df['订单日期'].str.replace('/', '-')   # 统一日期格式
    print(df['订单日期'].head(3))