解析缺失字段的制表符分隔文件

4 投票
3 回答
2120 浏览
提问于 2025-04-17 06:18

这是我正在尝试解析的一个复杂的制表符分隔文件的例子。

ENTRY   map0010\tNAME Glycolysis\tDESCRIPTION Glycolysis is the process of converting glucose into pyruvate\tCLASS   Metabolism\tDISEASE   H00071  Hereditary fructose intolerance\tH00072  Pyruvate dehydrogenase complex deficiency\tDBLINKS     GO: 0006096 0006094
ENTRY   map00020\tNAME  Citrate cycle (TCA cycle)\tCLASS   Metabolism; Carbohydrate Metabolism\tDISEASE   H00073  Pyruvate carboxylase deficiency\tDBLINKS     GO: 0006099\tREL_PATHWAY map00010  Glycolysis / Gluconeogenesis\tmap00053  Ascorbate and aldarate metabolism

我想得到的输出只包含一些特定的字段,比如:

ENTRY   map0010\tNAME Glycolysis\tCLASS   Metabolism\tDISEASE   H00071  Hereditary fructose intolerance H00072  Pyruvate dehydrogenase complex deficiency\tDBLINKS     GO: 0006096 0006094\tNA
ENTRY   map00020\tNAME  Citrate cycle (TCA cycle)\tCLASS   Metabolism; Carbohydrate Metabolism\tDISEASE   H00073  Pyruvate carboxylase deficiency\tDBLINKS     GO: 0006099\tREL_PATHWAY map00010  Glycolysis / Gluconeogenesis\tmap00053  Ascorbate and aldarate metabolism

主要的问题是,并不是所有的行都有相同数量的字段,所以我需要删除包含“DESCRIPTION”这个字符串的字段,并在那些没有“CLASS”字段的行中添加一个空字段。

而且,有些字段的数据被分成了多个部分(比如,第一行中,跟在“DISEASE”后面的字段包含了疾病的数据!),我需要把它们合并在一起。

我试过用:

input = open('file', 'r')

dict = ["ENTRY", "NAME", "CLASS", "DISEASE", "DBLINKS", "REL_PATHWAY"]

split_tab = []
output = []

for line in input:
    split_tab.append(line.split('\t'))

for item in dict:
    for element in split_tab:
        if item in element:
            output.append(element)
        else:
            output.append('\tNA\t')

但是它把所有的内容都保留了,而不仅仅是字典中指定的元素。你能帮我吗?

3 个回答

2

你这一行代码:

split_tab.append(line.split('\t'))

搞得有点乱。你是在一个列表里面再放一个列表。试试这样写:

split_tab = line.split('\t')

3

这段代码是用来做某些操作的,但具体的功能和背景信息没有提供。一般来说,代码块里包含了一些指令或者函数,这些指令会按照一定的顺序执行,从而实现特定的任务。

如果你看到这样的代码块,通常可以想象成是一个小工具,它可以帮助你完成某个具体的工作,比如计算、数据处理或者与用户互动等。理解这些代码的关键在于知道每一行代码的作用,以及它们是如何一起工作的。

如果你对代码的具体内容有疑问,可以尝试逐行分析,看看每一行在做什么,或者查找相关的资料来帮助你理解。

requiredKeys = 'ENTRY NAME CLASS DISEASE DBLINKS REL_PATHWAY'.split(' ')

for line in open('file', 'r'):
    fields = line.split('\t')
    fieldMap = {}
    for field in fields:
        key = field.split(' ', 1)[0]
        fieldMap[key] = field
    print '\t'.join([fieldMap.get(key, 'NA') for key in requiredKeys])
6

使用内置的 csv 库,这样你的工作会简单很多。

这里有一些示例代码:

import csv
reader = csv.reader(open('myfile.csv', 'rb'), dialect='excel-tab')
fieldnames = ['Name','Class']
writer = csv.DictWriter(open('myfile.csv', 'rb'), fieldnames, restval='', extrasaction='ignore', dialect='excel-tab')

for row in reader:
    newrow = {}
    for field in row:
        key = field.split(' ', 1)[0]
        newrow[key] = field
    writer.writerow(newrow)

特别注意一下如何设置 DictWriter。使用时如果包含 restvalextrasaction 字段,会简单得多。这两个字段可以让你传递一个字典,即使这个字典的值比写入器预期的多或少。

只需正确设置你的字段名称,并确保读取器使用正确的方言。这可能需要你自己添加一些内容,不过在 csv 的链接中有关于如何做到这一点的说明。

编辑

在下面 Rob 的评论发布后,我修改了这个内容,考虑到 csv 方言并没有我想象中那么强大。

撰写回答