你知道 Pandas 中 `pd.get_dummies()` 会生成哪些独热的新列么?

pd.get_dummies() 是 Pandas 中处理分类变量的核心函数,能一键将字符串/离散数值类型的分类特征转换为「哑变量/虚拟变量」(0-1 编码,独热编码)------ 这是解决机器学习模型无法直接处理非数值特征的关键步骤。

简单来说:一个包含 N 个不同分类值的列,会被转换成 N 个新的 0-1 (独热)列 (除非设置 drop_first=True),新列名的生成有明确规则。

二、新列名的生成规则(核心重点)

新列名的命名遵循「前缀 + 分隔符 + 分类值」的逻辑,默认规则和自定义规则如下:

1. 默认规则(最常用)
  • 前缀 = 原分类列的列名
  • 分隔符 = 下划线 _
  • 最终列名 = 原列名_分类值
2. 特殊场景的列名规则
场景 示例(原数据) 生成的新列名
字符串分类值 列名性别,值为男/女 性别_男性别_女
数值型分类值 列名学历,值为1/2/3 学历_1学历_2学历_3
多列同时转换 性别(男/女)+ 列城市(北京/上海) 性别_男性别_女城市_北京城市_上海
自定义分隔符 设置prefix_sep='-',列性别(男/女) 性别-男性别-女
自定义前缀 设置prefix='sex',列性别(男/女) sex_男sex_女
剔除首列(去重共线) 设置drop_first=True,列性别(男/女) 仅生成性别_女(删除第一个分类的列)

三、代码示例(直观理解列名生成)

下面的代码可以直接复制运行,覆盖核心场景:

python 复制代码
import pandas as pd

# 1. 创建测试数据(包含字符串、数值分类列)
df = pd.DataFrame({
    "性别": ["男", "女", "男", "女"],
    "学历": [1, 2, 3, 2],
    "城市": ["北京", "上海", "北京", "广州"]
})
print("原始数据:")
print(df)
print("-" * 50)

# 2. 基础用法:转换所有分类列(默认规则)
dummies_default = pd.get_dummies(df)
print("默认规则生成的哑变量(列名=原列名_分类值):")
print(dummies_default.columns.tolist())  # 打印所有新列名
print(dummies_default)
print("-" * 50)

# 3. 自定义分隔符
dummies_sep = pd.get_dummies(df, prefix_sep='-')
print("自定义分隔符(-)的列名:")
print(dummies_sep.columns.tolist())
print("-" * 50)

# 4. 剔除首列(避免多重共线性)
dummies_drop = pd.get_dummies(df, drop_first=True)
print("drop_first=True 后生成的列(删除每个分类的第一个列):")
print(dummies_drop.columns.tolist())
输出结果说明
  • 基础用法输出列名:['性别_女', '性别_男', '学历_1', '学历_2', '学历_3', '城市_上海', '城市_北京', '城市_广州']
  • 自定义分隔符输出列名:['性别-女', '性别-男', '学历-1', '学历-2', '学历-3', '城市-上海', '城市-北京', '城市-广州']
  • drop_first=True 输出列名:['性别_男', '学历_2', '学历_3', '城市_上海', '城市_广州'](删除了每个分类的第一个列)

四、补充事项

1. 空值处理:如果原列有 NaNpd.get_dummies() 会自动忽略该值,生成的哑变量列中对应行全为 0(也可通过 dummy_na=True 单独生成 原列名_nan 列)。
2. 指定转换列:可用 columns 参数指定只转换某几列,比如 pd.get_dummies(df, columns=['性别', '城市']) 仅转换性别和城市列。
3. 剔除首列(避免多重共线性)

1. 先理解:为什么分类变量的哑变量会产生共线性?

哑变量的本质是「互斥且穷尽」的------对于一个有 N 个分类的变量,生成的 N 个哑变量之间存在完全的线性依赖关系 (可以互相推导),没有独立的信息增量。从数学角度上讲,只有N-1 个自由变量,即:N-1 个哑变量就能完全表达原分类变量的所有信息

举个最直观的例子:

假设你有一个「性别」列(只有「男」「女」两个分类),用默认方式生成哑变量会得到两列:

  • 性别_男:1=男,0=女
  • 性别_女:1=女,0=男

这两列满足:性别_女 = 1 - 性别_男。也就是说,知道其中一列的值,就能100%推出另一列的值------这就是完全多重共线性

再举多分类例子(城市:北京/上海/广州):

生成3列哑变量后,城市_北京 = 1 - 城市_上海 - 城市_广州,依然是完全线性相关的。

2. 为什么共线性对建模有害?

多重共线性主要影响基于线性假设的模型(如线性回归、逻辑回归、岭回归等),核心问题有3个:

  • 模型系数(权重)的估计不稳定:微小的数据变化会导致系数大幅波动,无法反映变量的真实影响;
  • 系数的解释性失效:比如线性回归中,系数代表「其他变量不变时,该变量对目标的影响」,但共线性下「其他变量不变」的前提不成立;
  • 冗余计算:多余的列不会增加任何信息,只会增加模型的计算量,对建模毫无帮助。
3. 为什么删除第一列不会丢失信息?

删除第一个哑变量列后,剩余的列依然能完整表达原分类变量的所有信息,只是把「第一个分类」作为「基准类别」。

还是用「性别」举例:

  • 删除 性别_女(第一个列),只剩 性别_男
    • 性别_男=1 → 男
    • 性别_男=0 → 女(基准类别)
      信息完全没丢。

用「城市(北京/上海/广州)」举例:

  • 删除 城市_北京(第一个列),剩 城市_上海城市_广州
    • 0,0 → 北京(基准类别)
    • 1,0 → 上海
    • 0,1 → 广州
      所有城市信息依然完整。
说明
  • 不是所有模型都需要drop_first:比如决策树、随机森林、XGBoost等树模型对共线性不敏感(因为树模型是基于特征分裂,而非线性组合),删不删影响很小;但线性回归、逻辑回归、线性SVM等必须处理,否则会影响模型效果。
  • 基准类别的选择drop_first=True 删的是「按字母/数值排序的第一个分类」,如果想自定义基准类别(比如把「北京」设为基准),可以手动删除对应列,效果一致。
  • 适用场景:对线性假设的模型(如线性回归、逻辑回归)必须用;树模型等对共线性不敏感的模型,可删可不删(删了能减少特征数量,提升效率)。

记住

  1. pd.get_dummies() 核心作用是将分类变量转为 0-1 哑变量,解决非数值特征建模问题。
  2. 新列名默认规则为 原列名_分类值,可通过 prefix(自定义前缀)、prefix_sep(自定义分隔符)调整。
  3. drop_first=True 会删除每个分类变量的第一个哑变量列,是机器学习中避免多重共线性的常用操作。
相关推荐
aitoolhub2 小时前
自媒体视觉物料高效创作新路径:稿定设计如何用AI重构内容生产逻辑
大数据·人工智能·aigc·媒体
Guheyunyi2 小时前
智能巡检:技术融合与系统生成
大数据·人工智能·科技·安全·信息可视化
AI营销先锋2 小时前
原圈科技领跑破解B2B增长焦虑
大数据·人工智能·机器学习
国强_dev2 小时前
微服务设计模式在数据开发领域的应用实践
大数据·微服务
实验室管理云平台2 小时前
AI大数据动物疫病预防与控制管理系统云平台的数字化升级
大数据·人工智能
小五传输2 小时前
数据摆渡解决方案:平衡安全与效率的企业级选择
大数据·运维·安全
灰鲸广告联盟2 小时前
APP广告变现数据分析:关键指标与优化策略
大数据·网络·数据分析
Hello.Reader3 小时前
Flink OpenSearch SQL Connector Append/Upsert、动态索引、Exactly-Once 与性能调参
大数据·sql·flink