如何基于df1完整ID与df2字符串前缀合并两个DataFrame?
实现前缀匹配的DataFrame合并
方法一:使用apply结合字符串前缀匹配
这种方法直接遍历df2的每个id,查找df1中能作为其前缀的id,若存在则返回对应的col1值(若有多个匹配,优先选择最长的前缀),无匹配则返回NaN。
import pandas as pd import numpy as np # 定义原始数据 df1 = pd.DataFrame({'id':['XYZ', 'ABC1', 'CDS'], 'col1':[1,2,3]}) df2 = pd.DataFrame({'id':['XYZ1', 'XYZ2', 'ABC1', 'ABC11', 'CDSS', 'CDS', 'ABC2', 'ABC', 'XYA'], 'col2':[1,2,3,4,5,6,7,8,9]}) # 定义匹配函数 def match_prefix_col1(id_val): # 筛选df1中能作为当前id前缀的行 matched_rows = df1[df1['id'].apply(lambda x: id_val.startswith(x))] if not matched_rows.empty: # 若有多个匹配,取前缀最长的那一行的col1值 longest_match = matched_rows.loc[matched_rows['id'].str.len().idxmax()] return longest_match['col1'] return np.nan # 给df2添加col1列 df2['col1'] = df2['id'].apply(match_prefix_col1) # 查看结果 print(df2)
运行后得到目标结果:
id col2 col1 0 XYZ1 1 1.0 1 XYZ2 2 1.0 2 ABC1 3 2.0 3 ABC11 4 2.0 4 CDSS 5 3.0 5 CDS 6 3.0 6 ABC2 7 NaN 7 ABC 8 NaN 8 XYA 9 NaN
方法二:交叉连接+筛选+去重
这种方法通过交叉连接生成所有可能的组合,再筛选出符合前缀条件的行,最后保留每个df2 id的最长匹配项,再合并回df2。
import pandas as pd # 定义原始数据 df1 = pd.DataFrame({'id':['XYZ', 'ABC1', 'CDS'], 'col1':[1,2,3]}) df2 = pd.DataFrame({'id':['XYZ1', 'XYZ2', 'ABC1', 'ABC11', 'CDSS', 'CDS', 'ABC2', 'ABC', 'XYA'], 'col2':[1,2,3,4,5,6,7,8,9]}) # 交叉连接df1和df2 cross_join = df1.assign(temp_key=1).merge(df2.assign(temp_key=1), on='temp_key').drop('temp_key', axis=1) # 筛选df2的id以df1的id为前缀的行 filtered = cross_join[cross_join['id_y'].str.startswith(cross_join['id_x'])] # 添加前缀长度列,用于后续筛选最长匹配 filtered['prefix_length'] = filtered['id_x'].str.len() # 按前缀长度降序排序,每个df2 id只保留第一个(最长前缀)匹配项 filtered = filtered.sort_values('prefix_length', ascending=False).drop_duplicates('id_y', keep='first') # 将匹配结果合并回df2 result = df2.merge(filtered[['id_y', 'col1']], left_on='id', right_on='id_y', how='left').drop('id_y', axis=1) # 查看结果 print(result)
该方法逻辑直观,适合数据量不大的场景,同样能得到目标结果。
内容的提问来源于stack exchange,提问作者corianne1234
相关产品推荐
相关产品推荐

