基于多列值用Pandas高效匹配UUID的优化方案咨询
问题描述
有两个DataFrame:
df1: UUID Street Number City Munic 0 S1 1 C1 M1 1 S2 2A C2 M2 2 S3 3 C3 M3 3 S3 3 C3 M8 4 S1 1 C1 M1 lkp: UUID Street Number City Munic 0 U1 S1 1 C1 M1 1 U2 S2 2A C2 M2 2 U3 S3 3 C3 M3 ...
其中lkp包含30万+唯一行,df1行数在1k到50k之间且存在重复行。需求如下:
- 从
df1提取Street、Number、City、Munic列的值,在lkp中匹配相同行 - 匹配成功则更新
df1的UUID为lkp对应值 - 匹配失败则将该行写入“missing”文件(或DataFrame)
当前使用.iterows()遍历匹配,处理4k行耗时超4分钟,需要更高效的解决方案。
高效解决方案:使用Pandas的
merge向量化操作 .iterows()是逐行循环,效率极低,改用Pandas原生的merge(基于哈希表的向量化匹配),速度能提升几个数量级。具体步骤如下:
1. 准备查找映射表
先提取lkp中用于匹配的列和对应UUID(题目说明lkp是唯一行,无需去重):
lkp_mapping = lkp[['Street', 'Number', 'City', 'Munic', 'UUID']]
2. 执行左连接关联
用left_merge保留df1所有行,同时匹配lkp中的对应数据:
merged = df1.merge( lkp_mapping, on=['Street', 'Number', 'City', 'Munic'], how='left', suffixes=('_original', '_matched') )
3. 更新UUID并分离未匹配行
- 匹配成功的行,用
lkp的UUID替换df1原UUID - 未匹配的行(
UUID_matched为NaN)筛选出来作为缺失数据:
# 更新df1的UUID列 df1['UUID'] = merged['UUID_matched'] # 提取未匹配的行,保留匹配列 missing = merged[merged['UUID_matched'].isna()][['Street', 'Number', 'City', 'Munic']]
4. 保存缺失数据
将未匹配行写入文件(可按需调整格式):
# 保存为CSV,无索引无表头,和示例输出一致 missing.to_csv('missing.csv', index=False, header=False)
完整代码示例
import pandas as pd # 假设df1和lkp已通过pd.read_csv等方式加载完成 # 步骤1:准备映射表 lkp_mapping = lkp[['Street', 'Number', 'City', 'Munic', 'UUID']] # 步骤2:左连接关联 merged = df1.merge( lkp_mapping, on=['Street', 'Number', 'City', 'Munic'], how='left', suffixes=('_original', '_matched') ) # 步骤3:更新UUID并提取缺失行 df1['UUID'] = merged['UUID_matched'] missing = merged[merged['UUID_matched'].isna()][['Street', 'Number', 'City', 'Munic']] # 步骤4:保存缺失数据 missing.to_csv('missing.csv', index=False, header=False) # 输出处理后的df1(去掉未匹配行,和示例结果一致) print(df1.dropna(subset=['UUID']))
效率说明
merge是Pandas底层优化的向量化操作,基于哈希表实现匹配,处理50k行的df1+30万行的lkp,耗时通常在几秒内,远优于逐行循环。
内容的提问来源于stack exchange,提问作者HoBe
相关产品推荐
相关产品推荐

