数据清洗与去噪|从 data_engineering_book 吃透数据清洗与去噪的核心逻辑

11 阅读6分钟

开篇:为什么数据清洗是数据工程师的“主战场”?

数据工程的核心是让“原始数据”转化为“可用资产”,而数据清洗与去噪正是这一过程中最基础也最关键的一环——行业共识是,数据工程师约60%-80%的时间都消耗在数据清洗环节;更关键的是,劣质数据会直接导致后续分析、建模得出完全错误的结论。

今天我们结合开源项目「data_engineering_book」 github.com/datascale-a… 中《2.2 数据清洗与去噪》的核心内容,拆解工业级数据清洗的底层逻辑、实操方法,帮你从“会做清洗”到“做对、做好清洗”。

图4_1_数据清洗流水线.png

GitHub地址: github.com/datascale-a…

在线链接:datascale-ai.github.io/

一、先搞懂:原始数据里的“噪声”都藏在哪?

data_engineering_book 中明确指出:数据质量是数据价值的前提。原始数据(日志、埋点、业务库导出数据等)的“噪声”主要分5类,几乎覆盖所有业务场景:

噪声类型典型表现业务影响举例
缺失值订单地址为空、用户年龄字段缺失配送失败、用户分层分析遗漏关键维度
异常值传感器温度瞬间跳至1000℃、订单金额100万(均值仅100元)销量预测偏差、成本核算错误
重复值表单重复提交、数据同步重复写入用户数统计虚高、销售额重复计算
格式不统一日期混存“2024-05-01”/“2024/05/01”、金额带“元”时间维度聚合失败、数值计算无法执行
逻辑冲突注册时间晚于下单时间、库存数量为负数用户行为分析失真、库存管理决策失误

这些“噪声”如果不处理,后续所有数据工作都是“空中楼阁”——比如用含异常值的销售数据做预测,会直接高估/低估销量;用格式混乱的日期做聚合,会导致数据遗漏。

二、核心方法论:data_engineering_book的“诊断-处理-验证”闭环

data_engineering_book 把数据清洗拆解为可落地的三步闭环,而非简单的“删改数据”,这也是工业级清洗的核心思路:

1. 第一步:数据诊断——先定位噪声,再动手清洗

先通过量化分析明确问题,避免“盲洗”。推荐用Pandas做快速诊断,示例代码如下:

import pandas as pd
import matplotlib.pyplot as plt

# 读取原始数据
df = pd.read_csv("raw_business_data.csv")

# 1. 缺失值诊断:计算缺失占比
missing_ratio = df.isnull().sum() / len(df)
print("缺失值占比(仅展示>0的字段):\n", missing_ratio[missing_ratio > 0])

# 2. 异常值诊断:箱线图可视化(快速识别极值)
plt.figure(figsize=(10, 6))
df["order_amount"].plot(kind="box")
plt.title("订单金额箱线图(识别异常值)")
plt.show()

# 3. 逻辑校验:检查“注册时间>下单时间”的异常记录
invalid_time = df[pd.to_datetime(df["register_time"]) > pd.to_datetime(df["order_time"])]
print(f"时间逻辑冲突记录数:{len(invalid_time)}")

# 4. 格式校验:检查手机号格式是否合规
import re
def check_phone(phone):
    return bool(re.match(r"^1[3-9]\d{9}$", str(phone)))
df["phone_valid"] = df["phone"].apply(check_phone)
print(f"手机号格式错误数:{len(df[~df['phone_valid']])}")
2. 第二步:针对性清洗——按类型处理,而非“一刀切”

data_engineering_book 强调:清洗的核心是“适配业务场景”,而非单纯删除/填充。以下是工业级常用策略:

噪声类型核心处理策略示例代码(Pandas)
缺失值① 低占比(<1%)删除;② 分类字段用众数、数值字段用中位数;③ 高占比用建模预测df['address'] = df['address'].fillna("未知地址")
df['age'] = df['age'].fillna(df['age'].median())
异常值① 分位数截断;② 业务规则修正;③ 标记保留(不删除)q999 = df['order_amount'].quantile(0.999)
df.loc[df['order_amount']>q999, 'order_amount'] = q999
重复值按唯一标识去重,保留首次/最新记录df = df.drop_duplicates(subset=["order_id"], keep="first")
格式不统一标准化转换(日期/数值/字符串)df['order_time'] = pd.to_datetime(df['order_time']).dt.strftime("%Y-%m-%d")
df['amount'] = df['amount'].str.replace("元", "").astype(float)
逻辑冲突可修正则修正,不可修正则剔除df.loc[df['stock'] < 0, 'stock'] = 0(库存负数修正为0)
3. 第三步:清洗后验证——确保数据“真的干净”

清洗完成后,必须重复“诊断步骤”验证:

  • 缺失值、重复值占比是否降至可接受范围;
  • 异常值、格式问题是否解决;
  • 逻辑冲突记录是否清零/可控;
  • 清洗后数据是否符合业务规则(如金额≥0、库存≥0)。

三、工业级落地:data_engineering_book强调的4个关键原则

项目中特别提醒:数据清洗不是“一次性操作”,而是工程化闭环,核心要遵守4个原则:

  1. 可追溯:记录每一步清洗操作(哪些记录被删、哪些字段被填充、填充值来源),便于问题排查;
  2. 可复用:将清洗逻辑封装为函数/组件,适配不同数据集;
  3. 非侵入式:不修改原始数据,清洗后生成新表/新文件,保留原始数据溯源;
  4. 自动化:基于Airflow/Prefect调度,实现每日同步数据后自动清洗。

示例:封装可复用的清洗函数

def clean_missing_values(df, fill_rules):
    """
    通用缺失值清洗函数
    :param df: 原始DataFrame
    :param fill_rules: 填充规则字典,如{"address": "未知地址", "age": "median"}
    :return: 清洗后的DataFrame
    """
    df_clean = df.copy()
    for col, rule in fill_rules.items():
        if rule == "median":
            df_clean[col] = df_clean[col].fillna(df_clean[col].median())
        elif rule == "mode":
            df_clean[col] = df_clean[col].fillna(df_clean[col].mode()[0])
        else:
            df_clean[col] = df_clean[col].fillna(rule)
    return df_clean

# 调用函数:适配不同数据集的缺失值规则
fill_rules = {"address": "未知地址", "age": "median", "gender": "mode"}
df_clean = clean_missing_values(df, fill_rules)

四、最后:推荐这个宝藏开源项目

本文所有核心思路均来自「data_engineering_book」——这是一个面向数据工程师的开源学习手册,覆盖数据采集、清洗、存储、建模、部署全链路,内容均为工业级实战经验总结,而非纯理论。

👉 项目地址:github.com/datascale-a… 如果你是数据工程师、分析师、算法工程师,这个项目能帮你系统化构建数据工程知识体系,从“零散操作”升级为“工程化思维”。

总结

数据清洗与去噪是数据工程的“地基”,data_engineering_book 把复杂的清洗逻辑拆解为“诊断-处理-验证”的闭环,同时强调工程化、可复用的落地原则,帮我们跳出“重复造轮子”的误区。

推荐大家Star这个项目,也欢迎提Issue/PR一起完善——让更多数据工程师少走弯路,把时间花在更有价值的数据分析、建模上。