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

如何连接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实现

这是数据分析场景下最常用的方式,步骤清晰直观:

  1. 提取右表C列的唯一值
  2. 让左表和这些唯一值做交叉连接,得到左表每行对应每个C值的全量组合
  3. 用这个组合表和原右表做左连接,匹配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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:43:41