如何在Pandas中基于列表列实现任意匹配的左连接?
实现基于列表元素匹配的DataFrame左连接
问题描述
现有两个DataFrame:
df1:
| index | col_1 |
|---|---|
| 1 | 'a' |
| 2 | 'b' |
df2:
| index_2 | col_1 |
|---|---|
| A | ['a', 'c'] |
| B | ['a', 'd', 'e'] |
需要实现左连接:当df1的col_1值存在于df2的col_1列表中任意位置时,就完成匹配,最终得到如下结果:
| index | col_1_x | index_2 | col_1_y |
|---|---|---|---|
| 1 | 'a' | A | ['a', 'c'] |
| 1 | 'a' | B | ['a', 'd', 'e'] |
解决方案
可以通过pandas的explode方法先将df2中的列表拆分为单行元素,再进行左连接,最后还原原列表数据,具体代码如下:
import pandas as pd # 创建原始DataFrame df1 = pd.DataFrame({'index': [1, 2], 'col_1': ['a', 'b']}).set_index('index') df2 = pd.DataFrame({'index_2': ['A', 'B'], 'col_1': [['a', 'c'], ['a', 'd', 'e']]}).set_index('index_2') # 将df2的col_1列表拆分为单行,保留index_2 df2_exploded = df2.explode('col_1').reset_index() # df1和拆分后的df2做左连接 merged_temp = df1.reset_index().merge(df2_exploded, on='col_1', how='left') # 合并回原df2的列表数据,重命名列名 result = merged_temp.merge(df2.reset_index(), on='index_2', how='left') result = result.rename(columns={'col_1_x': 'col_1_x', 'col_1_y': 'col_1_y'}) # 整理最终结果的列顺序,过滤无法匹配的行 result = result[['index', 'col_1_x', 'index_2', 'col_1_y']].dropna(subset=['index_2']) print(result)
运行后输出结果:
index col_1_x index_2 col_1_y 0 1 a A [a, c] 1 1 a B [a, d, e]
说明
explode('col_1'):将df2中每个列表的元素拆分为单独行,让单个值可以和df1直接匹配- 两次
merge:第一次完成值的匹配关联,第二次还原df2中原有的列表数据 dropna(subset=['index_2']):过滤掉df1中无法匹配的行(比如示例中col_1='b'的行)
内容的提问来源于stack exchange,提问作者Kaushik J
相关产品推荐
相关产品推荐

