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

如何合并两个DataFrame并仅保留与df1行数一致的合并结果?

解决方案:合并DataFrame并保留指定次数的匹配行

当然可以实现这个需求!要做到基于指定列合并且结果行数与df1完全一致,核心是让df1的每一行仅对应df2中同组的第N个匹配项(按出现顺序计数)。下面是具体步骤和代码示例:

方法思路

我们可以通过给两个DataFrame的匹配组内添加序号,再基于「匹配列+序号」进行左连接,确保每个df1的行仅匹配df2中对应位置的行,从而严格控制结果行数与df1一致。

具体代码实现

import pandas as pd

# 初始化你提供的数据集
df1 = pd.DataFrame(
    [[1, 2.1, 5, 0, 'a'], [7, 2.3, 5, 1, 'b'], [0, 2, 0, 1, 'c'], [9, 4, 4, 1, 'd']],
    columns=list('ABCDE')
)
df2 = pd.DataFrame(
    [[3, 2, 5, 0, 1, 2], [3, 2.4, 5, 1, 9, 9], [9, 9, 5, 9, 4, 5], [0, 2, 5, 0, 1, 1], [1, 4, 4, 3, 8, 0]],
    columns=list('xBCyzw')
)

# 步骤1:给df1的每个(B,C)组添加匹配序号
df1['match_idx'] = df1.groupby(['B', 'C']).cumcount()

# 步骤2:给df2的每个(B,C)组添加匹配序号
df2['match_idx'] = df2.groupby(['B', 'C']).cumcount()

# 步骤3:基于(B,C,match_idx)进行左连接,确保行数与df1一致
merged_df = pd.merge(df1, df2, on=['B', 'C', 'match_idx'], how='left')

# 可选:删除临时的match_idx列
merged_df = merged_df.drop('match_idx', axis=1)

print(merged_df)

代码解释

  • groupby(['B', 'C']).cumcount():对每个(B,C)组合的行进行组内计数,从0开始递增。这样df1和df2中同一(B,C)组的第1行、第2行都会有相同的match_idx。
  • pd.merge(..., how='left'):以df1为基准进行左连接,只会保留df1中存在的行,且每个行仅匹配df2中同组同序号的行,完美保证结果行数与df1一致。
  • 如果df2中某个(B,C)组的行数少于df1中的对应组,那么多余的df1行在合并后对应的df2列会显示为NaN,这是符合预期的(因为没有匹配项)。

输出结果示例

运行上述代码后,合并后的DataFrame如下:

A    B  C  D E    x    y    z    w
0  1  2.1  5  0 a  NaN  NaN  NaN  NaN
1  7  2.3  5  1 b  NaN  NaN  NaN  NaN
2  0  2.0  0  1 c  NaN  NaN  NaN  NaN
3  9  4.0  4  1 d  1.0  3.0  8.0  0.0

可以看到,行数和df1完全一致(4行),只有df1中最后一行(B=4,C=4)在df2中有对应的匹配项,其他行因为df2没有同组同序号的匹配,所以df2的列显示为NaN。

扩展:如果需要保留指定次数的匹配(比如每组保留前2次)

如果你的需求是每组最多保留N次匹配,而不是严格和df1行数一致,可以在添加序号后过滤match_idx < N,再进行合并:

# 示例:每组最多保留2次匹配
max_matches = 2
df1_filtered = df1[df1.groupby(['B', 'C']).cumcount() < max_matches]
df2_filtered = df2[df2.groupby(['B', 'C']).cumcount() < max_matches]
merged_df = pd.merge(df1_filtered, df2_filtered, on=['B', 'C', 'match_idx'], how='left')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:30:11