为Pandas DataFrame添加条件计算列:比iterrows()更优的替代方法?
Pandas 替代 iterrows() 的高效列计算方法
针对你的需求,以下几种方法可以完全替代iterrows(),大幅提升运行效率并降低内存占用:
1. 用 np.where 实现向量化条件判断
这是最推荐的方案,完全基于向量化操作,性能最优:
import numpy as np # 先计算所有行共用的分子部分 numerator = SynergyTable['WinRate'] - 50 + SynergyTable['Delta1'] + SynergyTable['Delta2'] # 定义判断条件 ad_support_condition = ((SynergyTable['role'] == 'AD') & (SynergyTable['AllyPosition'] == 'Support')) | \ ((SynergyTable['role'] == 'Support') & (SynergyTable['AllyPosition'] == 'AD')) # 根据条件选择除数,直接生成新列 SynergyTable['MatchupScores'] = np.where(ad_support_condition, numerator / 2, numerator / 3)
向量化操作会将计算任务交给底层优化的C语言实现,比逐行循环快数倍甚至数十倍,且无需额外列表存储中间结果。
2. 用 Pandas loc 分条件赋值
逻辑清晰,适合需要分步处理的场景:
# 计算公共分子 numerator = SynergyTable['WinRate'] - 50 + SynergyTable['Delta1'] + SynergyTable['Delta2'] ad_support_condition = ((SynergyTable['role'] == 'AD') & (SynergyTable['AllyPosition'] == 'Support')) | \ ((SynergyTable['role'] == 'Support') & (SynergyTable['AllyPosition'] == 'AD')) # 先给所有行设置默认值(非AD-Support组合的情况) SynergyTable['MatchupScores'] = numerator / 3 # 再对满足条件的行覆盖赋值 SynergyTable.loc[ad_support_condition, 'MatchupScores'] = numerator.loc[ad_support_condition] / 2
这种方法通过批量赋值避免逐行遍历,同样具备优秀的性能表现。
3. 用 apply 快速改写(性能略逊于前两种)
如果想保留类似原代码的逻辑结构,apply比iterrows()更高效,但仍不如向量化方法:
def calculate_matchup_score(row): numerator = row['WinRate'] - 50 + row['Delta1'] + row['Delta2'] if (row['role'] == 'AD' and row['AllyPosition'] == 'Support') or (row['role'] == 'Support' and row['AllyPosition'] == 'AD'): return numerator / 2 return numerator / 3 SynergyTable['MatchupScores'] = SynergyTable.apply(calculate_matchup_score, axis=1)
apply本质还是逐行处理,但内部优化比iterrows()更好,适合快速迁移代码但对性能要求不极致的场景。
内容的提问来源于stack exchange,提问作者Tim Vowden
相关产品推荐
相关产品推荐

