Pandas中对比DataFrame及按基因ID匹配添加列并计算均值的技术问题
Pandas中对比DataFrame及按基因ID匹配添加列并计算均值的技术问题
嘿,看起来你想实现的需求是:根据gene_id匹配两个DataFrame,针对df_sets中每个基因对应的样本列表,从df_counts中提取这些样本的计数数值,最后计算均值并添加为新列对吧?你的初始思路是拆分样本列表为单独列再合并,但其实有更简洁灵活的方法,不用拆分列哦,咱们一步步来~
先回顾你的输入数据
首先确认下你的输入DataFrame结构,方便后续验证结果:
import pandas as pd d_sets = {'gene_id': ['g0', 'g2', 'g3'], 'set_1': [['P1-12', 'P1-25', 'P1-28',], ['P1-6', 'P1-12', 'P1-25'], ['P1-6', 'P1-25', 'P1-28']]} df_sets = pd.DataFrame.from_dict(data=d_sets) d_counts = {'gene_id': ['g0', 'g1', 'g2', 'g3'], 'P1-6': [1, 2, 5, 7], 'P1-12': [2, 4, 6, 5], 'P1-25': [5, 1, 2, 6], 'P1-28': [3, 8, 1, 2]} df_counts = pd.DataFrame.from_dict(data=d_counts)
优化方案:无需拆分样本列
你之前拆分set_1为多个列的操作其实没必要,反而会限制样本列表的灵活性(比如如果不同行的样本数量不一样,拆分就会出问题)。下面提供两种更高效的方法:
方法一:合并DataFrame后逐行计算均值
先将两个DataFrame按gene_id合并,然后直接针对每行的样本列表提取对应列的数值求平均:
# 合并两个DataFrame,保留所有需要的信息 df_merged = df_sets.merge(df_counts, on='gene_id') # 定义函数:对每行,根据set_1的样本列表计算均值 def get_set_mean(row): # 取出当前行的样本列表 sample_list = row['set_1'] # 从当前行中提取这些样本的计数,计算均值 return row[sample_list].mean() # 应用函数生成新列 df_merged['set_1_mean'] = df_merged.apply(get_set_mean, axis=1) # 如果你只需要原df_sets的内容加均值,可筛选列 df_result = df_merged[['gene_id', 'set_1', 'set_1_mean']] print(df_result)
输出结果:
gene_id set_1 set_1_mean 0 g0 [P1-12, P1-25, P1-28] 3.333333 1 g2 [P1-6, P1-12, P1-25] 4.333333 2 g3 [P1-6, P1-25, P1-28] 5.000000
方法二:利用索引直接定位(更高效,适合大数据量)
如果你的数据集很大,合并DataFrame会占用较多内存,推荐用索引直接定位基因和样本,避免全量合并:
# 将df_counts设置为gene_id为索引,方便快速查找 counts_indexed = df_counts.set_index('gene_id') # 对df_sets每行计算均值 df_sets['set_1_mean'] = df_sets.apply( lambda row: counts_indexed.loc[row['gene_id'], row['set_1']].mean(), axis=1 ) print(df_sets)
输出结果和方法一完全一致,但内存占用更低,速度更快,适合处理大规模数据。
结果验证
咱们手动算几个值确认一下:
- g0的样本是
P1-12(2)、P1-25(5)、P1-28(3),均值=(2+5+3)/3≈3.333 - g2的样本是
P1-6(5)、P1-12(6)、P1-25(2),均值=(5+6+2)/3≈4.333 - g3的样本是
P1-6(7)、P1-25(6)、P1-28(2),均值=(7+6+2)/3=5.0
完全符合预期~
备注:内容来源于stack exchange,提问作者emor
相关产品推荐
相关产品推荐

