【问题标题】:How to output only unique gene id's?如何仅输出唯一的基因 ID?
【发布时间】:2020-11-23 22:03:40
【问题描述】:

我正在使用nano 中的以下命令处理一个项目:

from Bio import SeqIO
import sys
import re 

     fasta_file = (sys.argv[1])
        for myfile in SeqIO.parse(fasta_file, "fasta"):
          if len(myfile) > 250:
           gene_id = myfile.id
           mylist = re.match(r"H149xcV_\w+_\w+_\w+", gene_id)
           print (">"+list.group(0)) 

及其提供以下输出:

    >H149xcV_Fge342_r3_h2_d1
    >H149xcV_bTr423_r3_h2_d1
    >H149xcV_kN893_r3_h2_d1
    >H149xcV_DNp021_r3_h2_d1
    >H149xcV_JEP3324_r3_h2_d1
    >H149xcV_JEP3324_r3_h2_d1
    >H149xcV_JEP3324_r3_h2_d1
    >H149xcV_JEP3324_r3_h2_d1
    >H149xcV_SRt424234_r3_h2_d1
    >H149xcV_SRt424234_r3_h2_d1
    >H149xcV_SRt424234_r3_h2_d1
    >H149xcV_SRt424234_r3_h2_d1

我如何更改我的命令,以便它为我提供唯一

>H149xcV_Fge342_r3_h2
>H149xcV_bTr423_r3_h2
>H149xcV_kN893_r3_h2
>H149xcV_DNp021_r3_h2
>H149xcV_JEP3324_r3_h2
>H149xcV_SRt424234_r3_h2

【问题讨论】:

    标签: python fasta nano


    【解决方案1】:

    您可以使用捕获组并在替换中使用它。

    为防止不必要的回溯,您可以使用否定字符类[^\W_]+从单词字符中排除下划线

    (H149xcV_[^\W_]+_[^\W_]+)_[^\W_]+
    

    Regex demo

    list = re.match(r"(H149xcV_[^\W_]+_[^\W_]+)_[^\W_]+", gene_id)
    print (">"+list.group(1)) 
    

    【讨论】:

    • 嗨@Thefourthbird,输出有效!现在的问题是我正在获取相同基因的重复,我尝试使用uniq 仅获取独特的基因,但它似乎不起作用?
    • @AlphaQueUp 将您的值添加到set
    • 我试过了,但还是不断重复。我不确定我是否正确编写了命令。
    • @AlphaQueUp 另请注意,您已将列表重命名为 mylist。在此处查看示例ideone.com/HimH0B
    • 嗨@Thefourthbird 抱歉,我只是无法集成到原始命令中,它仍然无法正常工作。有超过 20000 个基因 ID,我是否必须手动将我的值添加到集合中?
    【解决方案2】:

    您可以明确使用类,因为 \w+ 将匹配 [a-zA-Z0-9_] 所以即使您有多个 \w+ 也没关系。

    H149xcV_[a-zA-Z0-9]+_[a-zA-Z0-9]+_[a-zA-Z0-9]+
    

    Regex Demo

    在开发正则表达式时尝试使用正则表达式Cheatsheet,它有很大帮助。

    一个聪明的方法:

    (H149xcV(_[a-zA-z0-9]+){3})
    
    (                   start of group 1
    H149xcV             match literal text
    (                   start of sub-group 1
    _                   match underscore
    [a-zA-Z0-9]         word with digits
    +                   more than one occurrence
    )                   end of sub-group 1
    {3}                 should repeat 3 times 
    )                   end of group 1
    

    Regex Demo

    【讨论】:

    • 这是有道理的!谢谢!我应该在问题中提到,但有没有办法只获得独特的基因而不是重复?我尝试在命令行上使用sort|uniq,但它似乎不起作用? @KamranPervaiz
    • @AlphaQueUp 您可以使用re.findall 获取列表并使用set(mylist) 转换您的列表。看看这个答案stackoverflow.com/questions/40165530/…
    【解决方案3】:

    如果您只对正则表达式匹配的一部分感兴趣,请使用组来挑选出该部分:

    from Bio import SeqIO
    import sys
    import re 
    
    fasta_file = (sys.argv[1])
    for myfile in SeqIO.parse(fasta_file, "fasta"):
        if len(myfile) > 250:
            gene_id = myfile.id
            list = re.match(r"(H149xcV_\w+_\w+)_\w+", gene_id)
            print (">"+list.group(1)) 
    

    这应该可以为您提供所需的输出。

    您还询问了确保输出中没有重复项。为此,您需要记录您已经写过的内容,这意味着它们最终都在内存中 - 如果您仍然这样做,您最好在内存中构建列表并在完成后将其写入。这是假设您的数据集没有太大以至于无法放入内存。

    解决方案如下所示:

    from Bio import SeqIO
    import sys
    import re 
    
    fasta_file = (sys.argv[1])
    # by collecting results in a set, they are guaranteed to be unique
    result = set()
    for myfile in SeqIO.parse(fasta_file, "fasta"):
        if len(myfile) > 250:
            gene_id = myfile.id
            m = re.match(r"(H149xcV_\w+_\w+)_\w+", gene_id)
            if m.group(1) not in result:
                print(">"+m.group(1))
            result.add(m.group(1))
    

    另一种方法是构建result 并在完成后打印它,但这样做的缺点是结果不再与原始顺序相同,尽管它会更快一些(因为你不再有检查每一行是否有m.group(1) not in result)。

    【讨论】:

    • 是的,非常感谢! @Grismar我怎么能改变它,我只获得唯一的基因ID,现在我收到相同基因的重复。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-28
    • 1970-01-01
    • 2012-06-03
    • 2013-10-02
    • 2015-03-14
    • 2021-07-24
    相关资源
    最近更新 更多