如何优化Pandas双DataFrame SKU匹配迭代操作以提升运行速度
问题解答
1、当前写法是否为最高效方案?
完全不是,当前写法存在两个核心性能缺陷,是耗时过长的根本原因:
- 用
iterrows()逐行遍历30万行的pw表,pandas逐行迭代的性能远低于原生向量化操作,速度差可达数百倍 - 每次循环都对100万行的npw_inventory表做两次全表扫描:一次判断SKU是否存在,一次筛选匹配行,总时间复杂度达到O(30万 * 100万),是典型的低效操作
2、优化方案
核心优化思路
替换逐行循环逻辑,使用pandas原生向量化的merge操作完成匹配,时间复杂度可降至O(len(pw)+len(npw_inventory)),整体耗时可从2小时压缩到10秒以内。
优化后代码
import pandas as pd # 读取npw表时仅加载需要的3个字段,减少内存占用和读取耗时 npw_inventory = pd.read_csv( 'inventory/npw.csv', low_memory=False, usecols=['SKU', 'Core_cost', 'Min_order_Qty'], dtype={'SKU': str} # 提前指定SKU为字符串类型,避免类型不匹配导致匹配失败 ) # 若npw表存在重复SKU,先按业务需求去重,示例为保留第一条 npw_inventory = npw_inventory.drop_duplicates(subset='SKU', keep='first') # 批量生成pw表用于匹配的SKU字段(向量化操作,无循环) pw['match_sku'] = pw['CS-SKU-NP'].str[5:] # 一次左连接完成所有SKU匹配 pw = pw.merge(npw_inventory, left_on='match_sku', right_on='SKU', how='left') # 统计匹配成功的数量 match_success_count = pw['Core_cost'].notna().sum() # 批量更新匹配成功行的MinPrice(向量化计算) match_mask = pw['Core_cost'].notna() pw.loc[match_mask, 'MinPrice'] = (pw.loc[match_mask, 'MinPrice'] + pw.loc[match_mask, 'Core_cost']) * pw.loc[match_mask, 'Min_order_Qty'] # 清理匹配过程生成的多余字段,恢复pw表原有结构 pw = pw.drop(columns=['match_sku', 'SKU', 'Core_cost', 'Min_order_Qty']) print(match_success_count)
额外优化建议
- 如果npw表更新频率低,可提前将处理好的npw_inventory保存为pickle格式,下次加载速度比读CSV快5~10倍
- 若内存不足,可将npw_inventory的SKU字段设为索引,使用
map替代merge,内存占用更低
内容的提问来源于stack exchange,提问作者feners
相关产品推荐
相关产品推荐

