如何用pandas API基于复杂行条件为DataFrame高效新增特征列
pandas逐行多数投票特征高效实现
需求说明
现有如下0/1值DataFrame,需要新增一列实现行级投票逻辑:若某一行中值为1的元素占多数,新特征标记为1,否则标记为0。要求避免Python层逐行循环的低效率,使用pandas原生API实现高性能运算。
原始测试数据:
import pandas as pd df = pd.DataFrame({'col_a':[0,0,0,1,1,1], 'col_b':[1,0,0,1,0,1],'col_c':[1,0,0,1,0,1]}) print(df)
col_a col_b col_c 0 0 1 1 1 0 0 0 2 0 0 0 3 1 1 1 4 1 0 0 5 1 1 1
最优实现(向量化运算,性能最高)
利用pandas底层基于numpy的向量化运算,完全跳过Python层循环,1万行数据可在毫秒级完成计算,代码如下:
# 获取参与投票的总列数 total_cols = df.shape[1] # 逐行求和得到每行1的个数,判断是否超过半数,转成0/1整数赋值给新列 df['voter_result'] = (df.sum(axis=1) > total_cols / 2).astype(int)
运行后输出结果:
print(df)
col_a col_b col_c voter_result 0 0 1 1 1 1 0 0 0 0 2 0 0 0 0 3 1 1 1 1 4 1 0 0 0 5 1 1 1 1
实现说明
- 因为所有参与判断的值都是0/1,对行方向(
axis=1)求和的结果就是每行1的总个数,不需要额外做值筛选。 - 多数判定阈值为总列数的1/2,针对3列的测试数据阈值为1.5,即1的个数≥2时判定为多数,和需求逻辑完全匹配。
- 如果不需要所有列参与投票,只需要将
df替换为参与投票的列子集即可,例如df[['col_a','col_b','col_c']].sum(axis=1)。 - 如果存在偶数列平票场景,可根据业务需求调整判断条件:平票算1则将判断条件改为
>= total_cols / 2,平票需要自定义值可以用np.where做分支判断。
性能对比
- 逐行Python循环:1万行数据通常需要数秒到数分钟,耗时随数据量线性增长。
df.apply逐行调用:本质还是Python层循环,性能仅比手写循环好30%左右,依然不适合大数据量场景。- 本方案向量化运算:底层为C实现的批量运算,10万行以内数据耗时基本在10毫秒以内,性能是循环方案的数百到数千倍。
内容的提问来源于stack exchange,提问作者yonggir3213
相关产品推荐
相关产品推荐

