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

如何高效比较两个DataFrame并提取每行的共同元素?

提取两个DataFrame行内共同元素的解决方案

问题背景

需要对比两个行数一致、列数不同的DataFrame,行内元素顺序可变,要求提取每行中两个DF都存在的非NaN元素,整理为指定列数的结果,同时过滤掉无共同元素的行。

原始数据集

DF1

import pandas as pd
import numpy as np

df1 = pd.DataFrame({
    'Subj': ['Biotech', 'Zoology', 'Math', 'Microbio', 'Physics'],
    '1': ['Cell culture', 'Cell culture', 'Trigonometry', 'Biotech', 'Optics'],
    '2': ['Bioinfo', 'Immunology', 'Algebra', np.nan, np.nan],
    '3': ['Immunology', np.nan, np.nan, np.nan, np.nan]
})

DF2

df2 = pd.DataFrame({
    'Subj': ['Biotech', 'Zoology', 'Microbio', 'Physics', 'Math'],
    '1': ['Bioinfo', 'Immunology', np.nan, 'Optics', 'Trigonometry'],
    '2': ['Immunology', 'Botany', np.nan, 'Quantumphy', np.nan]
})

期望结果

# 输出示例
       Subj             1           2
0   Biotech       Bioinfo  Immunology
1   Zoology    Immunology         NaN
2      Math  Trigonometry         NaN
3   Physics        Optics         NaN

解决方案

核心思路是通过集合运算提取每行的共同元素,再规整为目标格式,适合大规模数据集:

# 辅助函数:提取单行非NaN元素的集合
def get_row_elements(row):
    return set(row.dropna().tolist())

# 为两个DF生成每行的元素集合(以Subj为索引)
df1_row_sets = df1.set_index('Subj').apply(get_row_elements, axis=1)
df2_row_sets = df2.set_index('Subj').apply(get_row_elements, axis=1)

# 计算每行的元素交集,过滤无共同元素的行
common_elements = df1_row_sets & df2_row_sets
common_elements = common_elements[common_elements.apply(len) > 0]

# 将集合转为列表,展开为指定列数(这里设为2列),不足补NaN
target_col_count = 2
result_df = common_elements.apply(
    lambda x: pd.Series(list(x) + [np.nan]*(target_col_count - len(x)))
).reset_index()

# 重命名列名
result_df.columns = ['Subj'] + [str(i) for i in range(1, target_col_count+1)]

print(result_df)

说明

  • 集合运算自动忽略元素顺序,完美匹配行内元素顺序可变的需求
  • 无需逐行遍历检查,处理大规模数据集效率更高
  • 可通过调整target_col_count参数适配不同的结果列数要求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 18:05:44