文本字段清洗:字符串、分类值与格式标准化

摘要

业务数据中大量字段都是文本,例如姓名、地区、渠道、订单状态、商品名称和备注。文本字段看似简单,却经常因为空格、大小写、别名、全角半角、非法字符和分类不统一,导致分组统计、筛选和匹配结果错误。

本文围绕 pandas 的字符串处理能力,介绍文本字段标准化、分类值映射、正则提取、非法值识别和清洗报告生成,帮助把混乱的文本字段整理为可分析、可复用的数据。

一、背景与问题

文本字段常见问题包括:

  • 同一地区出现 华东、华东 、East China。
  • 状态字段出现 Paid、paid、已支付、付款完成。
  • 商品名称中包含多余空格、换行符和特殊符号。
  • 手机号、订单号、门店编码格式不统一。
  • 人工填写的字段存在错别字和同义词。
  • 分类值数量膨胀,导致透视表和分组结果失真。

如果不处理这些问题,分组统计会变成:

text 复制代码
paid      100
Paid       32
已支付      8
付款完成     5

这些取值可能表示同一业务状态,却被当成不同类别。

文本清洗的目标不是"把字符串变好看",而是让文本字段具备稳定的业务含义。

二、核心概念

1. 字符串标准化

标准化是将不同写法统一为固定格式,例如:

  • 去除首尾空格。
  • 统一大小写。
  • 统一全角半角。
  • 去除多余换行和制表符。
  • 替换特殊符号。

标准化应尽量可解释,不要用过度复杂的规则误伤有效内容。

2. 分类值

分类值通常有有限取值集合,例如:

  • 订单状态:已支付、待支付、已取消、退款。
  • 地区:华东、华南、华北。
  • 渠道:官网、App、门店、第三方平台。

分类字段应该建立取值字典和映射规则。

3. 映射表

映射表用于把多个别名统一为标准值:

原始值 标准值
paid 已支付
Paid 已支付
付款完成 已支付
pending 待支付

映射表比散落在代码里的 if 判断更容易维护。

4. 正则表达式

正则适合处理格式化文本,例如提取编号、判断手机号、清理多余空白和识别特定模式。

正则很强大,但可读性较差。复杂规则应写注释并配套样例测试。

三、工作原理

1. 文本清洗流程

text 复制代码
读取原始文本
  → 转换为 string 类型
  → 基础标准化
  → 分类映射
  → 合法值检查
  → 无法识别值输出报告
  → 生成清洗字段

推荐保留原始列,并新增清洗后的标准列:

text 复制代码
status_raw     原始值
status_clean   标准值

2. 原始值与标准值

不要直接覆盖原始值。保留原始值有助于:

  • 追踪数据来源问题。
  • 优化映射表。
  • 审核清洗规则。
  • 处理争议记录。

3. 合法值校验

清洗后仍然需要检查是否存在未识别分类:

text 复制代码
标准值 ∈ 预定义枚举

未识别值不应该被悄悄归为"其他",除非业务明确允许。

四、实战示例

1. 准备示例数据

python 复制代码
import pandas as pd

df = pd.DataFrame(
    {
        "order_id": [" A001 ", "A-002", "A003\n", "a004"],
        "region": ["华东", "华东 ", "East China", "华南"],
        "status": ["Paid", "已支付", "付款完成", "pending"],
        "product": [" iPhone 15 ", "iPhone-15", "iphone 15", "苹果手机15"],
        "phone": ["138-0000-0000", "13800000001", " 13800000002 ", "invalid"],
    }
)

2. 转换为字符串类型

python 复制代码
text_columns = ["order_id", "region", "status", "product", "phone"]

for column in text_columns:
    df[column] = df[column].astype("string")

使用 pandas 的 string 类型可以更明确地处理缺失值和字符串方法。

3. 基础清洗

python 复制代码
def normalize_text(series: pd.Series) -> pd.Series:
    return (
        series.astype("string")
        .str.strip()
        .str.replace(r"\s+", " ", regex=True)
    )


df["order_id_clean"] = normalize_text(df["order_id"]).str.upper()
df["region_clean"] = normalize_text(df["region"])
df["status_clean"] = normalize_text(df["status"]).str.lower()
df["product_clean"] = normalize_text(df["product"]).str.lower()

\s+ 可以把多个连续空白字符替换为一个普通空格,包括换行和制表符。

4. 分类值映射

python 复制代码
status_mapping = {
    "paid": "已支付",
    "已支付": "已支付",
    "付款完成": "已支付",
    "pending": "待支付",
    "待支付": "待支付",
    "cancelled": "已取消",
    "已取消": "已取消",
}

df["status_standard"] = df["status_clean"].map(status_mapping)

映射失败的记录会得到缺失值,需要单独检查。

5. 地区映射

python 复制代码
region_mapping = {
    "华东": "华东",
    "east china": "华东",
    "华南": "华南",
    "south china": "华南",
}

df["region_standard"] = (
    df["region_clean"]
    .str.lower()
    .map(region_mapping)
)

如果映射表较大,可以把它维护在 Excel、CSV 或数据库中,由数据清洗程序读取。

6. 清洗手机号

python 复制代码
df["phone_clean"] = (
    df["phone"]
    .astype("string")
    .str.strip()
    .str.replace("-", "", regex=False)
    .str.replace(" ", "", regex=False)
)

df["phone_valid"] = df["phone_clean"].str.match(r"^1\d{10}$")
print(df[["phone", "phone_clean", "phone_valid"]])

手机号通常不应作为数值处理,否则可能丢失前导零或格式信息。

7. 提取订单编号

python 复制代码
df["order_number"] = (
    df["order_id_clean"]
    .str.extract(r"([A-Z]+[-]?\d+)", expand=False)
)

正则提取后要检查缺失结果,确认是否存在不符合格式的订单号。

8. 商品名称标准化

python 复制代码
product_mapping = {
    "iphone 15": "iPhone 15",
    "iphone-15": "iPhone 15",
    "苹果手机15": "iPhone 15",
}

df["product_standard"] = (
    df["product_clean"]
    .str.replace("-", " ", regex=False)
    .map(product_mapping)
)

商品名称标准化常常需要业务字典或商品主数据支持,不能完全依赖字符串规则。

9. 未识别值报告

python 复制代码
unknown_status = df.loc[
    df["status_standard"].isna(),
    ["order_id", "status", "status_clean"],
]

unknown_region = df.loc[
    df["region_standard"].isna(),
    ["order_id", "region", "region_clean"],
]

print(unknown_status)
print(unknown_region)

未识别值应进入人工复核或映射表维护流程。

10. 字段级清洗报告

python 复制代码
report = pd.DataFrame(
    [
        {
            "field": "status",
            "unknown_count": int(df["status_standard"].isna().sum()),
            "unique_raw": int(df["status"].nunique(dropna=True)),
            "unique_standard": int(df["status_standard"].nunique(dropna=True)),
        },
        {
            "field": "region",
            "unknown_count": int(df["region_standard"].isna().sum()),
            "unique_raw": int(df["region"].nunique(dropna=True)),
            "unique_standard": int(df["region_standard"].nunique(dropna=True)),
        },
    ]
)

print(report)

标准化后,唯一值数量通常会下降。如果下降过多,也可能说明规则过度合并。

五、常见问题与实践建议

1. 是否应该把所有文本都转小写?

不一定。状态、渠道等分类值可以统一大小写;姓名、品牌、产品型号等字段可能需要保留展示格式。可以使用一个字段做匹配,一个字段做展示。

2. 未识别值是否都归为"其他"?

不建议默认这样做。未识别值可能代表新业务类型或数据质量问题。可以先输出报告,确认后再决定是否归为"其他"。

3. 正则表达式越复杂越好吗?

不是。复杂正则很难维护,应优先使用简单、可解释的规则。复杂规则需要样例测试和注释。

4. 如何管理映射表?

小项目可以使用字典;稳定项目建议使用 CSV、Excel、数据库表或配置文件,并记录版本、维护人和更新时间。

5. 文本清洗会不会误伤数据?

会。比如去除所有空格可能让产品型号或地址失真。因此每条规则都要结合字段语义设计。

六、进阶思考

1. 建立标准字典

文本标准化的长期方案是建立主数据或标准字典,例如:

  • 地区字典。
  • 商品字典。
  • 渠道字典。
  • 状态枚举。
  • 组织机构字典。

清洗程序应尽量引用标准字典,而不是在代码中堆规则。

2. 模糊匹配

当文本存在错别字或相似名称时,可以使用模糊匹配辅助人工修正。但模糊匹配不应自动覆盖高风险字段,应输出候选项和置信度。

3. 清洗规则测试

为映射规则准备测试样例:

python 复制代码
def test_status_mapping() -> None:
    source = pd.Series(["Paid", "已支付", "付款完成"])
    result = source.astype("string").str.strip().str.lower().map(status_mapping)
    assert result.tolist() == ["已支付", "已支付", "已支付"]

规则变化后,测试可以避免旧数据被错误处理。

4. 从字段清洗到数据治理

如果同一个字段在多个系统中长期不一致,单靠分析端清洗无法根治。应推动数据源系统统一字段规范和枚举约束。

结论

文本字段清洗的核心是标准化、映射和校验。pandas 的字符串方法可以处理空格、大小写、替换和正则提取,映射表可以把别名统一为标准分类,清洗报告可以帮助持续优化规则。

下一篇将进入数据筛选与排序,学习如何构建可靠的数据子集,并为后续分组统计和业务分析准备干净的数据范围。

参考资料

  1. pandas 字符串方法:https://pandas.pydata.org/docs/user_guide/text.html
  2. pandas Series.str 文档:https://pandas.pydata.org/docs/reference/series.html#string-handling
  3. Python re 文档:https://docs.python.org/3/library/re.html
相关推荐
甲维斯1 小时前
Gemin4 很难说好,但也不算差!
人工智能
智慧物业老杨1 小时前
物业费催收难?数智化系统如何用技术重构“服务-收费“闭环
大数据·人工智能
u1301301 小时前
GitHub 热榜项目:日榜(2026-10-14)
人工智能·github
Raas1001 小时前
AI网关怎么选?MAI Gateway(魔芋企业级AI网关)入选2026年企业级AI网关推荐清单
大数据·网络·人工智能·gateway·mai gateway
晨间晓1 小时前
两张图片哪里不一样?用 OpenCV 做图像差异检测工具
人工智能·opencv·计算机视觉
逸A1 小时前
携程app逆向那些事(ai agent能力偏弱时)
人工智能·python·安全
恒拓高科WorkPlus1 小时前
企业IM、OA套件与数字协同平台怎么选?现有系统集成与采购成本对比
大数据·安全
汇智信科1 小时前
基于 SMS 体系的民航安全管理平台架构,危险源与事件闭环管理
人工智能·安全·汇智信科·hsim·fastclaw·汇智龙虾
数据皮皮侠1 小时前
中国产品级二氧化碳排放数据集
大数据·人工智能·搜索引擎·智慧城市·制造