4.3 类型转换编码与标准化


4.3 类型转换编码与标准化

本节摘要:数据"看起来有值"还不够,类型与量纲必须对。本节解决三类问题:类型错乱(数字存成字符串、日期不统一)、类别数据的编码(标签编码与独热编码)、数值特征的标准化(Min-Max 与 Z-score),并给出各自适用场景。

核心问题

阅读完本节,你应当能够:

  1. 用 astype、to_numeric、to_datetime 修正列类型
  2. 处理日期格式不统一的问题
  3. 区分标签编码与独热编码的适用场景
  4. 用 Min-Max 与 Z-score 完成数值标准化
  5. 说清标准化与归一化的区别

一、问题与直觉

"金额"列明明是数字,dtype 却是 object——因为它里面混了一两个带逗号的字符串"1,299",Pandas 只好整列降级成字符串。此时求和直接报错或结果全错。类型问题不解决,后面每一步都是雷。另一个常见困惑:分类变量"门店"直接喂给算法会被当成数字 1、2、3 的大小关系,必须编码成算法能理解的形式。

二、核心原理

2.1 类型的本质

Pandas 的每列都声明了 dtype。object 列(字符串)不能做数值运算;数值列混入字符串会自动降级。astype 是强转接口,pd.to_numeric 更宽容(能处理"1,299"这类带格式的文本)。

2.2 编码:给类别一个数字身份

  • 标签编码:把"北京、上海、广州"映射成 0、1、2。省空间,但引入了不存在的序关系
  • 独热编码:拆成三列(是否北京、是否上海、是否广州),每行只有一个 1。不引入序关系,但列数膨胀

💡 关键直觉:无序类别(门店、类目、颜色)用独热编码;有序类别(差评/中评/好评、小/中/大)才用标签编码。给"门店"编成 0/1/2 让算法以为广州大于北京,是常见错误。

2.3 标准化与归一化的区别

  • Min-Max 归一化:缩放到 [0, 1],(x - min) / (max - min)。受异常值影响大
  • Z-score 标准化:变成均值 0、标准差 1,(x - mean) / std。抗异常值更好

三、工程实践要点

3.1 类型修正

import pandas as pd # 字符串转数值(自动处理 "1,299" 这种格式) df["金额"] = pd.to_numeric(df["金额"], errors="coerce") # 强转类型 df["门店编号"] = df["门店编号"].astype(int) # 字符串转日期 df["日期"] = pd.to_datetime(df["日期"])

⚠️ 常见坑:to_numeric 遇到无法转换的值,加 errors="coerce" 会变成 NaN,而不是报错中断——这正好暴露出"藏得最深的问题值"。转换后务必检查新产生的 NaN,它们就是需要回头修的脏数据。

3.2 日期格式统一

df["日期"] = pd.to_datetime(df["日期"], format="%Y-%m-%d", errors="coerce")

format 明确告诉 Pandas 日期长什么样,errors="coerce" 把解析失败的变成 NaN 以便定位。格式混用的列("2026-01-01" 和 "20260102")在 to_datetime 面前也能统一。

3.3 类别编码

# 标签编码:手动映射或 factorize df["门店编码"] = df["门店"].astype("category").cat.codes # 独热编码 df_onehot = pd.get_dummies(df["门店"], prefix="门店") df = pd.concat([df, df_onehot], axis=1)

get_dummies 一行生成所有独热列,配合 concat 拼回原表。类别多时(几十个)考虑只用出现频次高的前 N 类做独热,其余归为"其他",避免列爆炸。

3.4 数值标准化

# Min-Max 归一化 df["金额归一"] = (df["金额"] - df["金额"].min()) / (df["金额"].max() - df["金额"].min()) # Z-score 标准化 df["金额标准"] = (df["金额"] - df["金额"].mean()) / df["金额"].std()

3.5 处理策略速查

数据形态 处理 典型场景
文本数字("1,299") to_numeric + coerce 金额、数量
日期格式不一 to_datetime + format 时间字段
无序类别 独热编码 门店、类目
有序类别 标签编码 评分、等级
量纲差异大 标准化 机器学习特征
有异常值的分布 Z-score 抗离群

3.6 实战:完整类型修正

df = pd.DataFrame({ "订单号": ["A001", "A002"], "金额": ["1,299", "89.5"], "日期": ["2026-01-01", "20260102"], "门店": ["北京", "上海"], }) df["金额"] = pd.to_numeric(df["金额"].str.replace(",", ""), errors="coerce") df["日期"] = pd.to_datetime(df["日期"], errors="coerce") df = pd.concat([df, pd.get_dummies(df["门店"], prefix="门店")], axis=1) print(df.dtypes) print(df)

金额、日期、门店三类问题一次解决,列类型全部正确。

3.7 常见类型问题速查

现象 原因 解法
数字列是 object 混入文本/千分位 to_numeric + errors="coerce"
日期是 object 格式不统一 to_datetime + format
布尔列是 object 存了"是/否"文本 map({"是": True, "否": False})
数值列出现 NaN 原值是空字符串 replace("", np.nan) 再处理
astype 报错 有无法转换的值 先 to_numeric 定位问题值

3.8 标准化的"什么时候做"与"什么时候不做"

标准化不是所有场景都要做:

  • 需要做:机器学习模型输入(KNN、SVM、神经网络对量纲敏感);多特征比较(金额与数量量纲差异大)
  • 不必做:树模型(决策树、随机森林、XGBoost 对单调变换不敏感);只看分布的探索阶段
  • 注意:标准化要在切分训练/测试集之后用训练集参数做,防止信息泄漏——这是建模前的硬性纪律

💡 关键直觉:先想清楚下游是谁。模型要"距离"就标准化,模型只"比较大小"就不用。标准化用错了场景,等于给数据强行套了不合适的尺子。

3.9 编码后的数据形态

独热编码后表会变宽,注意数据形态的变化:

df = pd.DataFrame({"门店": ["北京", "上海", "广州", "北京"]}) encoded = pd.get_dummies(df["门店"], prefix="门店") print(encoded) # 门店_北京 门店_上海 门店_广州 # 0 1 0 0 # 1 0 1 0 # 2 0 0 1 # 3 1 0 0

每行只有一个 1、其余为 0,这就是"独热"的含义。类别有几十个时,独热列数会爆炸——先用 value_counts 看分布,只对高频类建列,低频归入"其他"。

要点速记

  • 要点一:object 列先查有没有混字符串,to_numeric 加 coerce 修正并暴露问题值
  • 要点二:日期格式不一用 to_datetime 统一,format 参数加速且更准
  • 要点三:无序类别用独热编码,有序类别才用标签编码,别给无序数据强加顺序
  • 要点四:get_dummies 一行独热,类别过多时只保留高频类
  • 要点五:Min-Max 缩放到 0-1、Z-score 标准化到均值 0 标准差 1,有异常值优先 Z-score
  • 要点六:转换后检查新出现的 NaN,它们就是最后一批待修的脏数据

类型与量纲都对了,还剩最后一块硬骨头——异常值。下一节教你用 IQR 和 Z-score 把它们揪出来,并把整套清洗流程固化成管道。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U