如何提升Pandas处理7300万行DataFrame的匹配效率?
提升7300万行DataFrame匹配效率的解决方案
兄弟,你这代码跑慢完全是踩了Pandas的大忌——逐行循环遍历超大规模数据!7300万行的循环加上每次loc的索引扫描,时间复杂度直接拉满,15分钟没结束太正常了。咱们换用Pandas原生的矢量化操作,分分钟搞定。
问题根源
你原来的find_rating函数+列表推导,本质是把Pandas当成普通Python列表在用,完全没利用到它基于C底层的矢量化运算优势。每次loc查询都要扫描整个ratings表,7300万次重复扫描,速度能快才怪。
最优解决方案:用merge左连接+缺失值填充
直接用Pandas的merge做左连接,这是专门为「按键匹配」场景设计的矢量化操作,效率是循环的几百上千倍。
步骤如下:
- 先清理ratings的重复项(如果有的话),避免匹配后出现重复行
- 用
left_merge把bookmarks和ratings按双ID列连接 - 把连接后缺失的
score填充为0
具体代码:
# 第一步:清理ratings中的重复(profile,item)对,保留第一个得分 ratings_clean = ratings.drop_duplicates(subset=['id_profile', 'id_item'], keep='first') # 第二步:左连接bookmarks和清理后的ratings,确保bookmarks的所有行都保留 bookmarks_with_scores = bookmarks.merge( ratings_clean, on=['id_profile', 'id_item'], how='left' ) # 第三步:把缺失的score填充为0 bookmarks_with_scores['score'] = bookmarks_with_scores['score'].fillna(0)
备选优化:用复合索引加速查找
如果不想用merge,也可以给ratings设置复合索引,再用索引快速匹配:
# 给ratings设置复合索引并去重 ratings_indexed = ratings.set_index(['id_profile', 'id_item'])['score'].drop_duplicates() # 利用索引的哈希特性快速匹配,缺失值返回0 bookmarks['score'] = bookmarks.apply( lambda row: ratings_indexed.get((row['id_profile'], row['id_item']), 0), axis=1 )
不过这种方法的效率还是略逊于merge,merge是Pandas针对这类场景优化最到位的操作。
Colab额外优化建议
- 开启GPU加速:菜单栏→Runtime→Change runtime type→Hardware accelerator选GPU,Pandas的部分底层操作会自动利用GPU资源,进一步提速
- 内存优化:如果数据量接近Colab内存上限,可以用
dtype指定更小的数据类型(比如把id_profile设为int32),减少内存占用
内容的提问来源于stack exchange,提问作者Warsow




