如何高效比较两个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
相关产品推荐
相关产品推荐

