Pandas中替代逐行遍历高效实现关联取值计算的方法
高效实现方案
你当前用双层iterrows()实现的逻辑本质是值匹配映射,完全可以用pandas向量化操作替代,性能会有量级提升,不需要写任何显式循环。
测试数据复现
首先复现你给出的两个DataFrame(注意原遍历代码里的edges是df的笔误,apped是append的拼写错误,直接运行会报错):
import pandas as pd data ={'a':[1,2,3,4,5,6,7],'b':[2,5,3,6,1,7,4]} df = pd.DataFrame(data) data ={'a':[4,2,1,7,3,6,5],'c':[12,15,13,60,100,700,400]} df1 = pd.DataFrame(data)
预期输出结果:
[28, 415, 200, 712, 413, 760, 72]
实现代码
核心思路是先把df1构建成a列到c列的映射表,直接对df的两列做批量映射后求和,全程走pandas底层C实现的向量化逻辑,没有Python层循环开销:
# 构建a->c的映射关系 c_mapper = df1.set_index('a')['c'] # 批量映射两列后求和,转成列表 final = (df['a'].map(c_mapper) + df['b'].map(c_mapper)).tolist() print(final)
运行后直接得到预期输出。
方案说明
- 性能对比:双层
iterrows()的时间复杂度是O(nm),这个方案的时间复杂度是O(n+m)*,当数据量达到万级以上时,性能差距可以达到百倍甚至千倍 - 重复值处理:如果df1的
a列存在重复值,默认会保留最后一条匹配的c值,如果需要保留第一条匹配值,可以提前做去重处理:c_mapper = df1.drop_duplicates(subset='a', keep='first').set_index('a')['c'] - 缺失值处理:如果df里的a/b值在df1中找不到匹配项,
map会返回空值NaN,求和结果也会是NaN,如果需要给缺失值设置默认填充值,可以在map后追加.fillna(默认值)即可。
内容的提问来源于stack exchange,提问作者data en
相关产品推荐
相关产品推荐

