如何用Pandas高效计算DataFrame各列与最后一列匹配值的频率
问题分析
需求为创建名为freqs的列表,存储Pandas DataFrame中除最后一列外,各列元素与对应行最后一列值匹配的出现频率。
原有实现存在两类问题:
- 性能问题:使用
iterrows()逐行遍历是Pandas中最低效的操作之一,所有计算在Python层循环完成,数据量稍大时运行速度极慢,不符合Pandas向量化编程的惯用思路 - 语法错误:代码本身存在多处bug,无法正常运行:
df.colums属性名拼写错误(正确写法为df.columns)、result = row[-1]在row变量定义前就被调用、len_df未提前赋值。
最优Pandas实现方案
用Pandas原生的向量化广播操作替代显式循环,所有计算在底层C层完成,速度比逐行遍历快几十到上百倍,完全符合Pandas惯用写法,代码仅需两行:
# 提取最后一列作为匹配参照列 target = df.iloc[:, -1] # 逐列计算匹配频率并转为列表 freqs = (df.iloc[:, :-1] == target.values.reshape(-1, 1)).mean().tolist()
代码逻辑说明
df.iloc[:, :-1]:选中DataFrame中除最后一列外的所有待统计列target.values.reshape(-1, 1):将参照列转换为列向量,触发Pandas广播机制,一次性完成所有行、所有列的匹配判断,返回同尺寸的布尔DataFrame,值为True代表位置匹配,False代表不匹配.mean():按列计算布尔值的均值——由于布尔类型中True等价于1、False等价于0,列均值正好就是该列元素和参照列匹配的频率.tolist():将计算得到的频率Series直接转换为需要的列表格式
特殊场景适配
如果数据中存在缺失值NaN,不希望缺失值相等被判定为匹配,可以在比较时加入na=False参数:
freqs = (df.iloc[:, :-1] == target.values.reshape(-1, 1)).mean(na=False).tolist()
内容的提问来源于stack exchange,提问作者Siddhesh Agarwal
相关产品推荐
相关产品推荐

