如何无重复地对含指定标记的行进行FPKM与count值求和?
问题描述
现有一个包含Ko_class、FPKM、count列的Pandas DataFrame,数据如下:
Ko_class FPKM count 0 Carbon;Pyruvate;vitamins 16.7 1 1 Pyruvate;Carbohydrate;Pentose and glucuronate 30.0 7 2 Lipid;Carbon;Galactose 40.5 9 3 Galactose;Pyruvate;Fatty acid 57.0 10 4 Fatty acid;Lipid 22.0 4
需要根据target_list中的每个条目,对符合条件的行的FPKM和count值求和,规则为:
- 将target条目拆分为多个子类关键词
- 筛选原DataFrame中
Ko_class包含至少一个该target子类关键词的行 - 对这些行的
FPKM和count分别求和,每行仅被计入一次(即使匹配多个target关键词)
target_list内容:
target_list = ['Carbon','Carbon; Pyruvate','Galactose; Pyruvate; Carbon', 'Galactose;Pyruvate;Fatty acid; Carbon']
期望输出结果:
Ko_class FPKM count 0 Carbon 57.2 10 1 Carbon; Pyruvate 144.2 27 2 Galactose; Pyruvate; Carbon 144.2 27 3 Galactose;Pyruvate;Fatty acid; Carbon 166.2 31
解决方案
实现思路
- 统一处理关键词拆分:无论是原DataFrame的
Ko_class还是target条目,都按分号(含带空格的情况)拆分为关键词集合,方便快速判断交集。 - 遍历每个target,筛选符合条件的行:判断原行的关键词集合与target的关键词集合是否有交集,有交集则计入求和。
- 汇总求和结果并整理为目标DataFrame。
完整代码
import pandas as pd # 初始化原始数据 classes = [('Carbon;Pyruvate;vitamins', 16.7, 1), ('Pyruvate;Carbohydrate;Pentose and glucuronate', 30, 7), ('Lipid;Carbon;Galactose', 40.5, 9), ('Galactose;Pyruvate;Fatty acid', 57, 10), ('Fatty acid;Lipid', 22, 4)] labels = ['Ko_class','FPKM', 'count'] alls = pd.DataFrame.from_records(classes, columns=labels) # 处理原始数据的Ko_class,拆分为关键词集合 alls['ko_set'] = alls['Ko_class'].apply(lambda x: set(item.strip() for item in x.split(';'))) target_list = ['Carbon','Carbon; Pyruvate','Galactose; Pyruvate; Carbon', 'Galactose;Pyruvate;Fatty acid; Carbon'] # 存储每个target的求和结果 result_data = [] for target in target_list: # 拆分target为关键词集合 target_set = set(item.strip() for item in target.split(';')) # 筛选符合条件的行:ko_set与target_set有交集 filtered_rows = alls[alls['ko_set'].apply(lambda x: not x.isdisjoint(target_set))] # 求和 fpkm_sum = filtered_rows['FPKM'].sum() count_sum = filtered_rows['count'].sum() # 添加到结果列表 result_data.append({'Ko_class': target, 'FPKM': fpkm_sum, 'count': count_sum}) # 转换为DataFrame并输出 result_df = pd.DataFrame(result_data) print(result_df)
代码说明
alls['ko_set']:将每行的Ko_class拆分为去重的关键词集合,比如Carbon;Pyruvate;vitamins会转换为{'Carbon', 'Pyruvate', 'vitamins'}。target_set:对每个target做同样的拆分处理,兼容分号后带空格的情况(比如Carbon; Pyruvate拆分为{'Carbon', 'Pyruvate'})。not x.isdisjoint(target_set):判断两个集合是否有交集,只要有一个关键词匹配就保留该行。- 最后将每个target的求和结果整理为DataFrame,与期望输出完全一致。
内容的提问来源于stack exchange,提问作者yan wang
相关产品推荐
相关产品推荐

