pandas outer合并DataFrame筛选共有行时行数超出预期问题
问题原因
合并后行数超出预期,核心原因有两个:
- 基因ID存在重复:pandas做表合并时,只要关联键匹配就会生成对应行,如果某个Gene_ID在任意一个表中出现多次,就会产生一对多的匹配,行数自然增加。你现在结果多了4行,大概率是df1中存在4个重复的Gene_ID条目,每个重复项和df中对应ID匹配时都会多生成1行结果。
- 代码写法不严谨:一是没有显式指定
on参数声明合并关联键,虽然当前两个表只有Gene_ID是同名列,但这种写法容易受后续表结构变动影响;二是筛选both的代码漏了闭合单引号:df_merge['_merge'].eq('both)会直接触发语法错误,属于笔误。
另外你要取共有基因完全没必要先做outer join再筛选,直接用inner join效率更高。
解决步骤
- 先排查两个表的Gene_ID重复情况,确认重复条目:
# 统计两个表的重复Gene_ID数量 print(f"df中重复Gene_ID数:{df.duplicated(subset='Gene_ID').sum()}") print(f"df1中重复Gene_ID数:{df1.duplicated(subset='Gene_ID').sum()}") # 查看重复Gene_ID对应的具体条目 print(df1[df1.duplicated(subset='Gene_ID', keep=False)].sort_values('Gene_ID')) - 根据业务需求处理重复值,常规处理方式两种:
- 每个Gene_ID仅保留第一条出现的记录
- 对同一个Gene_ID对应的多个TPM值取平均
示例代码:
# 方式1:按Gene_ID去重,保留第一条记录 df1_clean = df1.drop_duplicates(subset='Gene_ID', keep='first') # 方式2:按Gene_ID分组,对scRNA_TPM取均值(适合重复ID对应不同表达值的场景) # df1_clean = df1.groupby('Gene_ID', as_index=False)['scRNA_TPM'].mean() # 如果df本身也存在重复ID,用同样逻辑处理即可 # df_clean = df.drop_duplicates(subset='Gene_ID', keep='first') - 显式指定关联键做内连接,直接获取共有基因的匹配结果:
shared_df = df.merge(df1_clean, on='Gene_ID', how='inner') - 结果校验,确认没有重复ID:
print(f"合并后结果行数:{len(shared_df)}") print(f"合并后重复Gene_ID数:{shared_df.duplicated(subset='Gene_ID').sum()}")
正常处理后得到的shared_df行数就会和预期一致,为2401行。
内容的提问来源于stack exchange,提问作者Caroline
相关产品推荐
相关产品推荐

