如何在Pandas中匹配两个DataFrame列值并新增对应topic列
实现方案
前置准备
先构造示例数据方便验证效果:
import pandas as pd # 最初需求的df1 # df1 = pd.DataFrame({ # 'name': ['Harry', 'Kenny', 'Zoey'], # 'value': ['a', 'b', 'h'] # }) # 更新需求后的df1 df1 = pd.DataFrame({ 'name': ['Harry Lee', 'Kenny', 'Zoey'], 'value': ['a', 'b', 'h'] }) df2 = pd.DataFrame({ 'list': ['Jame, Harry, Noah', 'lee, zee'], 'topic': ['topic1', 'topic2'] })
最初需求实现
逻辑是先把df2的list列拆分展开,生成「单个名字-对应topic」的映射表,直接匹配df1的name列即可:
# 预处理df2:拆分list列,展开为单条名字对应topic的结构 df2_explode = df2.assign(name=df2['list'].str.split(',\s*')).explode('name') name_to_topic = df2_explode.set_index('name')['topic'].to_dict() # 匹配填充present列 df1['present'] = df1['name'].map(name_to_topic).fillna('none')
运行后即可得到预期的最初需求输出。
更新需求实现
新增了全名拆分、多匹配结果拼接的要求,同时适配示例中Lee和lee大小写不敏感的匹配逻辑,实现如下:
# 第一步:预处理df2,生成统一小写的名字到topic的映射,避免大小写匹配失败 df2['name_parts'] = df2['list'].str.split(',\s*').apply(lambda x: [i.lower() for i in x]) name_topic_map = df2.explode('name_parts').groupby('name_parts')['topic'].apply(list).to_dict() # 第二步:定义匹配函数,拆分df1的全名后逐个匹配,拼接所有命中的topic def match_topics(full_name): # 拆分全名并统一转小写 parts = [p.lower() for p in full_name.split()] matched = [] for p in parts: if p in name_topic_map: matched.extend(name_topic_map[p]) # 去重后拼接,无匹配返回none return ' '.join(sorted(set(matched))) if matched else 'none' # 应用函数生成present列 df1['present'] = df1['name'].apply(match_topics)
运行后得到的df1即符合更新需求的预期输出:
| name | value | present | |
|---|---|---|---|
| 0 | Harry Lee | a | topic1 topic2 |
| 1 | Kenny | b | none |
| 2 | Zoey | h | none |
内容的提问来源于stack exchange,提问作者Tanishka Bansal
相关产品推荐
相关产品推荐

