如何用Pandas高效分组透视列生成哑变量(大数据场景)
如何高效地将Pandas DataFrame按分组转换C列为哑变量?
没问题,这个需求完全可以用Pandas实现,而且针对你提到的百万行、数千种C取值的大数据场景,我们有高效的方案。先来看你的数据示例:
import pandas as pd data = {'A' : ['000001','000001','000001','000001','000002','000002','000003'], 'B' : ['1A','1A','1C','1D','1A','1A','1D'], 'C' : ['003','012','016','003','020','012','053']} df = pd.DataFrame(data)
下面给你两种高效的实现方法,适配不同的数据规模:
方法1:使用pd.crosstab(直观易读)
pd.crosstab天生就是用来生成这类交叉标记表的,它会自动按A、B分组,统计每个组内各C值的出现情况,我们只需要把计数转成0/1即可:
# 生成交叉表,以A、B为行索引,C的取值为列 result = pd.crosstab(index=[df['A'], df['B']], columns=df['C']) # 将计数转为0/1(只要出现过就标记为1) result = result.applymap(lambda x: 1 if x > 0 else 0) # 把A、B从索引转回普通列 result = result.reset_index() # 给列名加上C_前缀,匹配你的需求格式 result.columns = ['A', 'B'] + [f'C_{col}' for col in result.columns[2:]]
方法2:get_dummies + groupby.max(超大数据量首选)
如果你的数据集达到数百万行级别,这个方法的效率会更高——get_dummies是向量化操作,groupby.max也是Pandas高度优化的聚合方法:
# 对C列生成哑变量,自动添加C_前缀 dummies = pd.get_dummies(df['C'], prefix='C') # 合并原数据的A、B列和哑变量列 df_with_dummies = pd.concat([df[['A', 'B']], dummies], axis=1) # 按A、B分组,取每组最大值(存在的C值对应列保留1,否则为0) result = df_with_dummies.groupby(['A', 'B']).max().reset_index()
最终输出结果
运行任意一种方法后,你都会得到符合预期的格式:
A B C_003 C_012 C_016 C_020 C_053 0 000001 1A 1 1 0 0 0 1 000001 1C 0 0 1 0 0 2 000001 1D 1 0 0 0 0 3 000002 1A 0 1 0 1 0 4 000003 1D 0 0 0 0 1
大数据场景优化提示
- 如果C的取值有数千种,生成的哑变量列会很多,此时可以在
get_dummies中添加sparse=True参数,生成稀疏矩阵来节省内存:dummies = pd.get_dummies(df['C'], prefix='C', sparse=True) - 方法2的向量化操作避免了额外的计数计算,在百万级数据集上的运行速度会明显优于
crosstab。
内容的提问来源于stack exchange,提问作者jma




