Python如何将多列转为统一OneHotEncoding分类列避免列名重复
全局统一独热编码实现方案
直接对多列DataFrame调用pd.get_dummies()默认会按列生成带前缀的编码列,跨列的同值分类会产生冗余列,要实现全局唯一分类对应单一编码列,用全局打平再聚合的方案即可,全程pandas原生实现,不需要额外依赖。
示例数据复现
首先复现问题中的测试数据集,注意原示例中写的字符串"NaN"建议替换为pandas可识别的空值np.nan,避免被识别为有效分类:
import pandas as pd import numpy as np cat_1 = ["A", "B", "C", "D"] cat_2 = ["C", "A", "E", "A"] cat_3 = [np.nan, "F", np.nan, np.nan] data_dict = {'image_1': cat_1, 'image_2': cat_2, 'image_3': cat_3} df = pd.DataFrame(data_dict)
如果你数据里的空值确实是字符串格式的"NaN",后续加一步替换即可。
核心实现代码
# 若空值为字符串"NaN"先执行这行替换,是np.nan则跳过 df = df.replace("NaN", np.nan) # 全局独热编码核心逻辑 result = pd.get_dummies(df.stack(dropna=True))\ .groupby(level=0)\ .max()\ .reindex(df.index, fill_value=0)
逻辑说明
df.stack(dropna=True):将原多列数据打平为双层索引的一维序列,第一层索引为原行号,第二层为原列名,同时自动剔除空值,此时所有列的分类值都被放到同一个全局序列里- 对打平后的序列调用
pd.get_dummies():此时同一个分类值只会生成一个独热列,不会带原列名前缀 groupby(level=0).max():按原行号分组聚合,只要某行任意一列出现过对应分类值,该分类列就取1(独热值只有0/1,用max不会因为同值出现多次产生大于1的结果)reindex(df.index, fill_value=0):补全所有列都是空值的行的编码结果,避免行丢失
效果说明
最终输出结果每个全局唯一分类值仅对应一列,不存在冗余:
| 行号 | A | B | C | D | E | F |
|---|---|---|---|---|---|---|
| 0 | 1 | 1 | 1 | 0 | 0 | 0 |
| 1 | 1 | 0 | 0 | 0 | 0 | 1 |
| 2 | 0 | 0 | 1 | 0 | 1 | 0 |
| 3 | 1 | 0 | 0 | 1 | 0 | 0 |
如果你需要统计每行某分类出现的次数而非是否存在,把代码里的
.max()替换为.sum()即可。
内容的提问来源于stack exchange,提问作者Ilayda Göden
相关产品推荐
相关产品推荐

