You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

优化Pandas DataFrame映射方法:补全无名称ID的对应名称

Pandas高效匹配未映射ID的优化方案

问题背景

我有一个已完成名称与ID匹配的Pandas DataFrame,但部分ID未匹配到名称。需要回到映射文件(mapping_df)的alternative_ID_list列,忽略小数部分,为这些ID匹配对应名称(若存在多个匹配则取首个)。但我当前的实现方法运行耗时过长,求优化。

现有数据

当前匹配结果(current_df)

current_df = pd.DataFrame({
    'name': ['joe', 'mary', 'USER3', 'USER4', 'USER5', 'USER6'],
    'ID': ['USER1', 'USER2', 'USER3', 'USER4', 'USER5', 'USER6']
})
# 需要处理的未匹配ID:USER3、USER4、USER5、USER6

映射表(mapping_df)

mapping_df = pd.DataFrame({
    'name': ['joe', 'mary', 'sam', 'jack', 'rick', 'john', 'jay'],
    'ID': ['USER1', 'USER2', 'USER98', 'USER992', 'USER902', 'USER979', 'USER980'],
    'alternative_ID_list': [
        'USER213.32',
        'USER643.11',
        'USER31.5',
        'USER4.2',
        'USER5.6, USER321.1',
        'USER6.8, USER987.9',
        'USER479.2, USER989.0'
    ]
})

期望结果

# 处理后的DataFrame
    name     ID
0    joe  USER1
1   mary  USER2
2  USER3  USER3
3   jack  USER4
4   rick  USER5
5   john  USER6

原低效实现(耗时过长)

df2 = current_df
bad_matches = df2['ID'].loc[df2['name'].isna()]

mapping_df.alternative_ID_list = mapping_df.alternative_ID_list.str.split(',')
mapping_df = mapping_df.explode('alternative_ID_list')

mapping_df.alternative_ID_list = mapping_df.alternative_ID_list.astype(str).str.split('.').str[0].astype(str)

df3 = mapping_df.loc[lambda x: x['alternative_ID_list'].isin(bad_matches)]

df2['name'] = df2['ID'].map(df3.set_index('alternative_ID_list')['name']).fillna(df2['name'])

优化方案

核心思路

  • 避免全量拆分、爆炸映射表,仅处理需要匹配的bad_matches
  • 用字典存储映射关系,实现O(1)快速查找
  • 找到首个匹配后立即终止,减少不必要计算

优化代码

import pandas as pd

# 1. 提取需要处理的未匹配ID(根据实际情况调整判断逻辑)
bad_matches = current_df.loc[current_df['name'].str.startswith('USER'), 'ID'].tolist()
# 若原逻辑是name为空:bad_matches = current_df['ID'].loc[current_df['name'].isna()].tolist()

# 2. 构建仅包含目标ID的映射字典
id_name_map = {}

for _, row in mapping_df.iterrows():
    # 拆分并清洗alternative ID:去空格、截断小数部分
    alt_ids = [id_str.strip().split('.')[0] for id_str in row['alternative_ID_list'].split(',')]
    # 遍历当前行的备选ID,仅处理未被映射的目标ID
    for alt_id in alt_ids:
        if alt_id in bad_matches and alt_id not in id_name_map:
            id_name_map[alt_id] = row['name']
            break  # 找到首个匹配就停止,避免后续覆盖

# 3. 批量更新名称列
current_df['name'] = current_df['ID'].map(id_name_map).fillna(current_df['name'])

# 输出结果
print(current_df)

优化效果说明

  • 内存占用大幅降低:无需生成爆炸后的大映射表
  • 计算效率提升:仅遍历一次映射表,且每个目标ID仅匹配一次
  • 字典映射比DataFrame的map操作更快,适合大规模数据场景

内容的提问来源于stack exchange,提问作者youtube

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 09:18:28