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

pandas如何对DataFrame取交集且不生成额外重复列

问题描述

对两个结构相同的pandas DataFrame做交集操作时,无论是用pd.merge还是pd.concat,都会生成带后缀的重复列,无法得到预期的纵向拼接、带来源标记的交集结果。

示例数据

两个测试用DataFrame列名完全一致,仅列A的取值范围有重叠:

import pandas as pd
import numpy as np

df1 = pd.DataFrame(
    data = np.stack([
        np.arange(4),
        np.random.rand(4),
        np.random.rand(4),
    ],axis=-1),
    columns = ["A","B","C"]
)
df2 = pd.DataFrame(
    data = np.stack([
        np.arange(4)+2,
        np.random.rand(4),
        np.random.rand(4),
    ],axis=-1),
    columns = ["A","B","C"]
)

两个DataFrame的输出示例:

(     A         B         C
 0  0.0  0.165849  0.516438
 1  1.0  0.116661  0.395433
 2  2.0  0.758229  0.386642
 3  3.0  0.057719  0.802317,
      A         B         C
 0  2.0  0.899924  0.545800
 1  3.0  0.792242  0.187410
 2  4.0  0.332168  0.778160
 3  5.0  0.164429  0.509884)

预期输出

需要保留两个DataFrame中A列取值重叠的行,同时增加Source列标记数据来源,结果为纵向拼接格式,无重复列:

Source     A         B         C 
 2  df1        2.0  0.758229  0.386642
 3  df1        3.0  0.057719  0.802317
 0  df2        2.0  0.899924  0.545800
 1  df2        3.0  0.792242  0.187410

已尝试的错误方案

方案1:用pd.concat横向拼接

将A设为索引后做横向内连接,会直接把两个表的非连接列横向并排,生成重复列名:

for df in [df1,df2]:
    df.set_index("A",inplace=True)

df = pd.concat([df1,df2],join="inner",axis=1).reset_index()

输出结果:

A   B         C         B         C
0   2.0 0.758229  0.386642  0.899924  0.54580
1   3.0 0.057719  0.802317  0.792242  0.18741

方案2:用pd.merge内连接

直接按A列做内连接,非连接列会自动加_x/_y后缀,同样是横向拼接的重复列:

df = pd.merge(
    left = df1,
    right = df2,
    how="inner",
    on = "A"
)

输出结果:

A   B_x       C_x       B_y       C_y
0   2.0 0.758229  0.386642  0.899924  0.54580
1   3.0 0.057719  0.802317  0.792242  0.18741

解决方案

之前的方法核心问题是拼接方向搞错了:axis=1的concat、默认的merge都是横向拼接,会把两个表的列并排展开,同名列必然重复。需求本身是纵向堆叠行,用默认axis=0的concat,提前筛掉A列不在交集内的行即可,代码非常简洁:

# 提取两个表A列的共有取值
common_a = np.intersect1d(df1['A'], df2['A'])

# 分别筛选交集行、加来源标记,最后纵向拼接
res = pd.concat([
    df1[df1['A'].isin(common_a)].assign(Source='df1'),
    df2[df2['A'].isin(common_a)].assign(Source='df2')
], ignore_index=False)[['Source','A','B','C']]

运行结果和预期完全一致:

Source    A         B         C
2    df1  2.0  0.758229  0.386642
3    df1  3.0  0.057719  0.802317
0    df2  2.0  0.899924  0.545800
1    df2  3.0  0.792242  0.187410

如果需要重置行索引,在代码末尾加.reset_index(drop=True)即可。


内容的提问来源于stack exchange,提问作者carlitador

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 11:09:23