如何在Pandas中对列表类型列实现高效类VLOOKUP匹配
高效Pandas多对一匹配优化方案
原有双层循环实现的时间复杂度为O(n*m),数据量增大后耗时会呈平方级上涨,优化核心是提前构建值到ID的哈希映射,将查询复杂度降到O(1),全程使用pandas向量化接口替代Python原生循环,性能可提升数十到上百倍。
实现代码
import pandas as pd # 原始测试数据 data = [['123', ['135', '987']], ['456', ['246', '000', '111']], ['789', ['369']]] df = pd.DataFrame(data, columns=['case_id', 'case_num']) data1 = [[' ', '135'], [' ', '000'], [' ', '369']] df_target = pd.DataFrame(data1, columns=['case_id', 'case_num']) # 步骤1:展开源df的嵌套case_num列表,构建case_num -> case_id的哈希映射 # explode方法会把列表中的每个元素拆分为单独行 num_id_map = df.explode('case_num').set_index('case_num')['case_id'].to_dict() # 步骤2:批量匹配赋值,直接替换原df_target的case_id字段 df_target['case_id'] = df_target['case_num'].map(num_id_map)
执行后得到的df_target结果如下,完全符合预期:
| case_id | case_num |
|---|---|
| 123 | 135 |
| 456 | 000 |
| 789 | 369 |
特殊场景适配
如果存在同一个case_num匹配到多个case_id的需求(即保留原逻辑的列表输出),只需要调整映射构建逻辑即可:
# 一对多场景:将同一个case_num对应的所有case_id聚合为列表 num_id_map_multi = df.explode('case_num').groupby('case_num')['case_id'].agg(list).to_dict() # 匹配后case_id字段会存储匹配到的所有id组成的列表 df_target['case_id'] = df_target['case_num'].map(num_id_map_multi)
性能说明
- 原双层循环是Python层逐行遍历,每次成员判断都要遍历整个列表,效率极低
- 优化后的实现所有展开、聚合操作均由pandas底层C实现的向量化逻辑完成,字典查询为哈希匹配,百万级数据量也能在秒级完成计算
内容的提问来源于stack exchange,提问作者Dynasty2468
相关产品推荐
相关产品推荐

