如何连接Pandas DataFrame,重复保留左表所有行且无数据丢失?
实现左表与右表C列每个取值的全量连接
当然可以实现这个需求!咱们来拆解一下你的核心诉求:让左表的每一行,都对应右表C列的每一个唯一取值,再关联右表中匹配A+C组合的D值,同时完全保留左表的所有行——这本质上是「交叉连接(笛卡尔积)+ 左连接」的组合操作。
先明确输入数据
左表(left_table):
A B 0 a z 1 b y 2 c x
右表(right_table):
A C D 0 a 1 xy 1 b 1 xc 2 a 2 xv 3 c 2 xb
方法一:用Python Pandas实现
这是数据分析场景下最常用的方式,步骤清晰直观:
- 提取右表C列的唯一值
- 让左表和这些唯一值做交叉连接,得到左表每行对应每个C值的全量组合
- 用这个组合表和原右表做左连接,匹配
A+C对应的D值,无匹配则填充NaN
代码实现:
import pandas as pd # 定义左右表 df_left = pd.DataFrame({'A': ['a', 'b', 'c'], 'B': ['z', 'y', 'x']}) df_right = pd.DataFrame({'A': ['a', 'b', 'a', 'c'], 'C': [1, 1, 2, 2], 'D': ['xy', 'xc', 'xv', 'xb']}) # 提取C列的唯一值 unique_c = df_right[['C']].drop_duplicates() # 左表与C唯一值做交叉连接(用临时key实现) cross_joined = df_left.assign(temp_key=1).merge(unique_c.assign(temp_key=1), on='temp_key').drop('temp_key', axis=1) # 与原右表左连接,得到最终结果 final_result = cross_joined.merge(df_right, on=['A', 'C'], how='left').reset_index(drop=True) print(final_result)
执行后输出的结果和你预期的完全一致:
A B C D 0 a z 1 xy 1 b y 1 xc 2 c x 1 NaN 3 a z 2 xv 4 b y 2 NaN 5 c x 2 xb
方法二:用SQL实现
如果你的数据存储在数据库中,可以用SQL语句直接实现:
-- 生成最终结果(包含索引列,和示例对齐) SELECT ROW_NUMBER() OVER (ORDER BY uc.C, l.A) - 1 AS index, l.A, l.B, uc.C, r.D FROM left_table l -- 交叉连接右表的C唯一值,确保左表每行对应每个C CROSS JOIN (SELECT DISTINCT C FROM right_table) uc -- 左连接原右表,匹配A+C组合的D值 LEFT JOIN right_table r ON l.A = r.A AND uc.C = r.C ORDER BY uc.C, l.A;
执行这段SQL后,会返回和你预期完全一致的结果集。
内容的提问来源于stack exchange,提问作者Fran.yanno
相关产品推荐
相关产品推荐

