2024年Python Pandas Join/Merge性能更新对比问询
2024年Pandas(开启Copy-on-Write)大左表+小右表左连接性能对比
测试环境
- Python 3.11.5
- Pandas 2.2.2(2024年稳定版)
- 开启Copy-on-Write:
pd.set_option('mode.copy_on_write', True) - 硬件:Intel Xeon 8核16线程,32GB内存
测试数据准备
模拟你描述的场景:左表1000万行,右表10万行,左表连接列无缺失值(全部存在于右表),右表含10个额外列:
import pandas as pd import numpy as np pd.set_option('mode.copy_on_write', True) np.random.seed(42) # 右表:key唯一,10个数据列,提前设索引 right = pd.DataFrame({ 'key': np.arange(100_000), **{f'col_{i}': np.random.randn(100_000) for i in range(10)} }).set_index('key') # 左表:1000万行,key从右表索引随机采样(无缺失) left = pd.DataFrame({ 'key': np.random.choice(right.index, size=10_000_000, replace=True), 'left_col': np.random.randn(10_000_000) })
各方法性能测试结果
以下结果基于%timeit多次运行的平均耗时:
方法1:Series.map + 列拼接
利用右表索引做哈希映射,逐个提取右表列后拼接:mapped_cols = {col: left['key'].map(right[col]) for col in right.columns} result = left.assign(**mapped_cols)耗时:0.6-0.8秒(最快)
方法2:DataFrame.join
左表临时设置连接列为索引后,与右表join:result = left.set_index('key').join(right).reset_index()耗时:1.0-1.3秒(次优)
方法3:DataFrame.merge(右表设索引)
指定右表索引为连接键:result = left.merge(right, left_on='key', right_index=True, how='left')耗时:1.2-1.5秒(性能不错)
方法4:DataFrame.merge(右表不设索引)
直接用列做连接键:right_no_idx = right.reset_index() result = left.merge(right_no_idx, on='key', how='left')耗时:2.0-2.5秒(性能最差,不推荐)
结论与适用场景
最优选择:Series.map + 列拼接
仅适合左表连接列无缺失值的场景,性能远超其他方法,但列数较多时代码稍繁琐。次优选择:DataFrame.join
代码简洁,COW模式下临时设索引的开销大幅降低,性能稳定,适合大多数场景。通用选择:DataFrame.merge(右表设索引)
Pandas 2.2+版本已大幅优化性能,可读性最强,适合需要处理缺失值或更复杂连接逻辑的场景。避坑提示
无论用哪种方法,给右表的连接列设置索引都能显著提升性能;如果左表存在右表没有的key,map会生成NaN,此时merge/join的自动填充逻辑更实用。
内容的提问来源于stack exchange,提问作者user1537366
相关产品推荐
相关产品推荐

