如何用Python解析层级keg数据并格式化为TSV文件
问题描述
我有一份带层级信息和KO编号的keg格式数据集,想用Python转换成TSV文件。要求:
- TSV第一列是KO编号,第二列是描述信息,第三列是基于最近'A'段的层级结构,需包含'A'、'B'、'C'开头的元素直到最近的'C'段;
- 同一KO编号对应不同层级时,用'|'在同一行分隔。
下面是输入数据、预期输出和我写的代码,求指导怎么正确实现需求。
输入数据
A09100 Metabolism B B 09101 Carbohydrate metabolism C 00010 Glycolysis / Gluconeogenesis [PATH:ko00010] D K00844 HK; hexokinase [EC:2.7.1.1] D K12407 GCK; glucokinase [EC:2.7.1.2] D K00001 E1.1.1.1, adh; alcohol dehydrogenase [EC:1.1.1.1] B 09103 Lipid metabolism C 00071 Fatty acid degradation [PATH:ko00071] D K00001 E1.1.1.1, adh; alcohol dehydrogenase [EC:1.1.1.1] A09120 Genetic Information Processing B B 09121 Transcription C 03020 RNA polymerase [PATH:ko03020] D K03043 rpoB; DNA-directed RNA polymerase subunit beta [EC:2.7.7.6] D K13797 rpoBC; DNA-directed RNA polymerase subunit beta-beta' [EC:2.7.7.6]
预期输出
KO metadata_KEGG_Description metadata_KEGG_Pathways K00844 HK; hexokinase [EC:2.7.1.1] Metabolism, Carbohydrate metabolism, Glycolysis / Gluconeogenesis K12407 GCK; glucokinase [EC:2.7.1.2] Metabolism, Carbohydrate metabolism, Glycolysis / Gluconeogenesis K00001 E1.1.1.1, adh; alcohol dehydrogenase [EC:1.1.1.1] Metabolism, Carbohydrate metabolism, Glycolysis / Gluconeogenesis|Metabolism, Lipid metabolism, Fatty acid degradation K03043 rpoB; DNA-directed RNA polymerase subunit beta [EC:2.7.7.6] Genetic Information Processing, Transcription, RNA polymerase K13797 rpoBC; DNA-directed RNA polymerase subunit beta-beta' [EC:2.7.7.6] Genetic Information Processing, Transcription, RNA polymerase
我的代码
data = """A09100 Metabolism B B 09101 Carbohydrate metabolism C 00010 Glycolysis / Gluconeogenesis [PATH:ko00010] D K00844 HK; hexokinase [EC:2.7.1.1] D K12407 GCK; glucokinase [EC:2.7.1.2] D K00001 E1.1.1.1, adh; alcohol dehydrogenase [EC:1.1.1.1] B 09103 Lipid metabolism C 00071 Fatty acid degradation [PATH:ko00071] D K00001 E1.1.1.1, adh; alcohol dehydrogenase [EC:1.1.1.1] A09120 Genetic Information Processing B B 09121 Transcription C 03020 RNA polymerase [PATH:ko03020] D K03043 rpoB; DNA-directed RNA polymerase subunit beta [EC:2.7.7.6] D K13797 rpoBC; DNA-directed RNA polymerase subunit beta-beta' [EC:2.7.7.6]""" lines = data.split('\n') result = [] ko = None description = None hierarchy_names = [] for line in lines: parts = line.strip().split() if parts: if parts[0].startswith('A'): # Reset hierarchy for a new 'A' section hierarchy_names = [" ".join(parts[1:])] elif parts[0] == 'K': ko = parts[0] description = " ".join(parts[1:]) elif parts[0] == 'D' and len(parts) >= 3: ko = parts[1] description = " ".join(parts[2:]) else: hierarchy_names.append(" ".join(parts[1:])) if ko and description: hierarchy_str = ", ".join(hierarchy_names) result.append([ko, description, hierarchy_str]) # Add the header row result.insert(0, ["KO", "metadata_KEGG_Description", "metadata_KEGG_Pathways"]) # Specify the filename for the TSV file tsv_filename = "output_data.tsv" with open(tsv_filename, 'w') as tsv_file: for row in result: tsv_file.write("\t".join(row) + "\n") print(f"Data saved to {tsv_filename}")
问题分析与修正方案
你的代码存在两个核心问题:
- 层级维护混乱:会把空的'B'行加入层级列表,且新的B/C层级只会追加不会替换,导致层级字符串冗余错误;
- 重复KO未合并:同一KO对应多个层级时会生成多条记录,没有按要求用'|'合并。
修正后的代码
data = """A09100 Metabolism B B 09101 Carbohydrate metabolism C 00010 Glycolysis / Gluconeogenesis [PATH:ko00010] D K00844 HK; hexokinase [EC:2.7.1.1] D K12407 GCK; glucokinase [EC:2.7.1.2] D K00001 E1.1.1.1, adh; alcohol dehydrogenase [EC:1.1.1.1] B 09103 Lipid metabolism C 00071 Fatty acid degradation [PATH:ko00071] D K00001 E1.1.1.1, adh; alcohol dehydrogenase [EC:1.1.1.1] A09120 Genetic Information Processing B B 09121 Transcription C 03020 RNA polymerase [PATH:ko03020] D K03043 rpoB; DNA-directed RNA polymerase subunit beta [EC:2.7.7.6] D K13797 rpoBC; DNA-directed RNA polymerase subunit beta-beta' [EC:2.7.7.6]""" lines = data.split('\n') # 用字典存储KO的描述和层级集合,自动去重合并 ko_dict = {} current_a = "" current_b = "" current_c = "" for line in lines: line = line.strip() if not line: continue # 只分割第一部分,保留描述中的空格 parts = line.split(maxsplit=1) if len(parts) < 1: continue if parts[0].startswith('A'): current_a = parts[1] if len(parts) > 1 else parts[0] current_b = "" current_c = "" elif parts[0] == 'B': # 跳过空的B行 if len(parts) > 1: current_b = parts[1] elif parts[0] == 'C': if len(parts) > 1: # 去掉PATH后缀,只保留路径名称 current_c = parts[1].split(' [PATH')[0] elif parts[0] == 'D': d_parts = parts[1].split(maxsplit=1) if len(d_parts) < 2: continue ko_id = d_parts[0] desc = d_parts[1] # 组装完整层级字符串 hierarchy = ", ".join([current_a, current_b, current_c]) # 更新字典:已存在则添加层级,不存在则新增 if ko_id in ko_dict: ko_dict[ko_id]['hierarchies'].add(hierarchy) else: ko_dict[ko_id] = { 'description': desc, 'hierarchies': {hierarchy} } # 生成最终结果列表 result = [["KO", "metadata_KEGG_Description", "metadata_KEGG_Pathways"]] # 按KO编号排序输出 for ko_id in sorted(ko_dict.keys()): info = ko_dict[ko_id] # 用|分隔多个层级 hierarchy_str = '|'.join(info['hierarchies']) result.append([ko_id, info['description'], hierarchy_str]) # 写入TSV文件,指定编码避免乱码 tsv_filename = "output_data.tsv" with open(tsv_filename, 'w', encoding='utf-8') as tsv_file: for row in result: tsv_file.write("\t".join(row) + "\n") print(f"数据已保存到 {tsv_filename}")
修正说明
- 精准层级维护:单独维护
current_a/current_b/current_c变量,跳过空B行,自动去除C行的[PATH:xxx]后缀; - 字典去重合并:用字典存储每个KO的信息,层级用集合自动去重,同一KO的多个层级最终用'|'连接;
- 字符串分割优化:用
split(maxsplit=1)确保描述中的空格不被拆分,保留完整描述内容; - 编码规范:指定
utf-8编码写入文件,避免特殊字符乱码。
内容的提问来源于stack exchange,提问作者Umar
相关产品推荐
相关产品推荐

