【问题标题】:Using regex to transform data into a dictionary in Python在 Python 中使用正则表达式将数据转换为字典
【发布时间】:2012-09-18 15:43:32
【问题描述】:

我有一个带有FASTA 格式排序的数据集,基本上是这样的:

>pc284  
ATCGCGACTCGAC

>pc293  
ACCCGACCTCAGC

我想将每个标签作为字典中的键,并将基因存储为值。

这是我的代码,但实际上什么也没做:

import re
fileData = open('d.fasta', 'r')

myDict = dict()

for line in fileData:
  match = re.search('(\>)(\w+)(\r)(\w+)', line)
  if match: 
    gene = match.group(3)
    myDict[gene[0]] = gene[1]

print myDict

【问题讨论】:

  • 您无法匹配回车符\r,因为您已经逐行扫描文件。

标签: python regex dictionary bioinformatics


【解决方案1】:

我看到了两个错误:

您的正则表达式可能是错误的。您的 FASTA 输入实际上不太可能包含裸回车符 (\r),因此您的正则表达式不会匹配任何内容。因此if match: 测试总是错误的,所以什么也没有发生。

此外,在处理每个匹配项时:您将添加gene(即空格)的第一个字符作为键,将第二个字符作为值。

您可能打算分别使用第 2 组和第 4 组:

myDict[match.group(2)] = match.group(4)

【讨论】:

    【解决方案2】:

    \r 不是有效的字符类,我认为您的意思是改用\s。如果你也不使用它们,你可以减少它们。

    但最重要的是,您需要正确提取组:

    match = re.search(r'>(\w+)\s+(\w+)', line)
    if match:
        tag, gene = match.groups()
        myDict[tag] = gene
    

    通过仅创建两个捕获组,我们可以更简单地使用.groups() 提取这两个并将它们直接分配给两个变量,taggene

    然而,阅读FASTA format 似乎表明这是一种多行格式,标签在一行,基因数据在多个行之后。在这种情况下,您的 \r 旨在匹配换行符。当您一次读取一行文件时,这将不起作用。

    如果没有像这样的正则表达式,阅读该格式会简单得多:

    myDict = {}
    
    with open('d.fasta', 'rU') as fileData:
        tag = None
        for line in fileData:
            line = line.strip()
            if not line:
                continue
            if line[0] == '>':
                tag = line[1:]
                myDict[tag] = ''
            else:
                assert tag is not None, 'Invalid format, found gene without tag'
                myDict[tag] += line
    
    print myDict
    

    这会逐行读取文件,根据起始 > 字符检测标签,然后读取 多行 行基因信息,将其收集到您的字典中最近读取的标签下。

    注意rU 模式;我们使用 python 的universal newlines mode 打开文件,以处理用于创建文件的任何换行约定。

    最后但并非最不重要的;看看BioPy project;他们的Bio.SeqIO module 可以完美处理 FASTA 以及许多其他格式。

    【讨论】:

    • @log0: 支持作为普通字符,也就是说在逐行读取文件时不起作用。
    • 当我尝试这个时,它会将整个遗传信息存储为一个标签,而不是单独的值。
    • @gr8skillz: 遗传信息中是否有换行符或\r 字符作为一个值存储?
    • 该代码适用于我的简单测试输入,但如果文件在行尾没有正确拆分,它将失败。
    • @gr8skillz:我在文件 open() 调用中添加了一个U。如果这对您不起作用,您能否提供一个示例文件?
    【解决方案3】:

    除非您的文件太大而无法放入内存(我猜不是),否则整个事情就像

    with open('d.fasta') as fp:
        myDict = dict(re.findall(r'(?m)^>(\w+)\s+^(\S+)', fp.read()))
    

    【讨论】:

      【解决方案4】:

      不要为此使用正则表达式...

      class FASTA(object):
          def __init__(self,data):
              self.data = data.strip().splitlines()
              self.desc = self.data[0]
              self.sequence = "".join(self.data[1:]).replace(" ","")#get rid of spaces
          def  GetCodons(self):
              return [self.sequence[i:i+3] for i in range(0,len(self.sequence),3)]
          def __str__(self):
              return "DESC:'%s'\nSEQ:'%s'"%(self.desc,self.sequence)
      
      with open("data.fasta") as f:
            data = f.read()
      parts = data.split(">")
      for p in parts[1:]:
          f= FASTA(p)
          print f
          print f.GetCodons()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-11-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-13
        相关资源
        最近更新 更多