Python中如何根据DataFrame列值生成特征列表与计数列
Pandas 按行统计值为1的列生成列表与计数最优方案
核心优先使用向量化运算避免逐行循环,兼顾性能与灵活性,适配任意特征列名。
实现代码
import pandas as pd # 1. 构造示例数据(替换成你自己的DataFrame即可) df = pd.DataFrame({ 'Text': ['string1', 'string2', 'string3'], 'feat1': [1, 0, 0], 'feat2': [1, 0, 0], 'feat3': [0, 0, 0], 'feat4': [0, 1, 0] }) # 2. 指定特征列范围:这里排除非特征列Text即可,有其他非特征列可自行增删排除项 feat_cols = df.columns.drop('Text') # 3. 生成all_feat列:收集每行值为1的特征列名 # 向量化点乘实现,性能远高于逐行apply df['all_feat'] = df[feat_cols].eq(1).dot(feat_cols + ',').str.rstrip(',').str.split(',').apply(lambda x: [] if x == [''] else x) # 4. 生成count_feat列:直接取列表长度,无需重复计算 df['count_feat'] = df['all_feat'].str.len()
方案说明
- 性能表现:核心逻辑用矩阵点乘做批量计算,没有Python层的逐行遍历开销,十万到百万级数据量下,运行速度是普通
apply写法的10~100倍。 - 灵活适配:不需要硬编码特征列名,只要调整
feat_cols的筛选规则即可,不管特征列名是中文、特殊字符还是任意长度字符串都能正常运行。 - 边界兼容:自动处理全0行场景,正确返回空列表与计数0,和需求规则完全匹配。
- 注意事项:如果你的特征列名本身包含英文逗号,把代码里拼接的分隔符换成列名中不会出现的字符(比如
|、@@等)即可,核心逻辑不需要改动。
小数据量简化写法
如果你的数据量在万行以内,性能差异感知不到,可以用可读性更高的列表推导写法:
# 替换上面步骤3的all_feat生成逻辑即可 df['all_feat'] = [ [col for col, val in row.items() if val == 1] for row in df[feat_cols].to_dict('records') ] df['count_feat'] = df['all_feat'].str.len()
运行结果
执行后输出的DataFrame完全符合预期:
Text feat1 feat2 feat3 feat4 all_feat count_feat 0 string1 1 1 0 0 [feat1, feat2] 2 1 string2 0 0 0 1 [feat4] 1 2 string3 0 0 0 0 [] 0
内容的提问来源于stack exchange,提问作者merchmallow
相关产品推荐
相关产品推荐

