如何根据DataFrame中二值列取值拼接列名生成新类别列
Pandas 基于二值列拼接生成分类列实现
核心思路
遍历每一行数据,筛选出A/B/C列中取值为1的列名,用+拼接为字符串;若所有列取值均为0,则赋值为None。
实现方法
方法1:逐行apply适配小数据集
代码逻辑简单直观,适合行数不多的场景:
- 预先指定需要处理的二值列列表
- 逐行匹配取值为1的列名,拼接后对空值做兜底替换
import pandas as pd # 构造示例数据 df = pd.DataFrame({ 'date': pd.to_datetime([ '02/19/2020','02/20/2020','02/21/2020','02/22/2020', '02/23/2020','02/24/2020','02/25/2020','02/26/2020' ]), 'A': [0,0,1,0,0,0,1,1], 'B': [0,0,1,1,1,0,0,0], 'C': [0,0,1,0,1,1,1,0] }) # 生成new列 target_cols = ['A', 'B', 'C'] df['new'] = df[target_cols].apply( lambda row: '+'.join([col for col in target_cols if row[col] == 1]) or 'None', axis=1 )
方法2:向量化运算适配大数据集
通过布尔矩阵和列名的矩阵乘法实现无循环计算,行数较多时性能远优于逐行apply:
target_cols = ['A', 'B', 'C'] # 构造值为1的布尔掩码 mask = df[target_cols].eq(1) # 列名拼接的基础向量 col_vec = pd.Series(target_cols, index=target_cols) # 矩阵乘法得到拼接后的字符串,去掉末尾多余的+,替换空字符串为None df['new'] = mask.dot(col_vec + '+').str.rstrip('+').replace('', 'None')
输出校验
两种方法执行后,生成的new列和需求示例完全一致:
| date | A | B | C | new |
|---|---|---|---|---|
| 2020-02-19 | 0 | 0 | 0 | None |
| 2020-02-20 | 0 | 0 | 0 | None |
| 2020-02-21 | 1 | 1 | 1 | A+B+C |
| 2020-02-22 | 0 | 1 | 0 | B |
| 2020-02-23 | 0 | 1 | 1 | B+C |
| 2020-02-24 | 0 | 0 | 1 | C |
| 2020-02-25 | 1 | 0 | 1 | A+C |
| 2020-02-26 | 1 | 0 | 0 | A |
内容的提问来源于stack exchange,提问作者lamlamboy
相关产品推荐
相关产品推荐

