Py学习  »  Python

基于python中两个短序列的过滤行

John • 4 年前 • 948 次点击  

我有一个类似于以下示例的文本文件:

例子:

>chr9:128683-128744
GGATTTCTTCTTAGTTTGGATCCATTGCTGGTGAGCTAGTGGGATTTTTTGGGGGGTGTTA
>chr16:134222-134283
AGCTGGAAGCAGCGTGAATAAAACAGAATGGCCGGGACCTTAAAGGCTTTGCTTGGCCTGG
>chr16:134226-134287
GGAAGCAGCGTGGGAATCACAGAATGGACGGCCGATTAAAGGCTTTGCTTGGCCTGGATTT
>chr1:134723-134784
AAGTGATTCACCCTGCCTTTCCGACCTTCCCCAGAACAGAACACGTTGATCGTGGGCGATA
>chr16:135770-135831
GCCTGAGCAAAGGGCCTGCCCAGACAAGATTTTTTAATTGTTTAAAAACCGAATAAATGTT

这个文件被分成不同的部分,每个部分有两行第一排以 > (这一行叫做id),第二行是字母序列。 我想找两个短的主题( AATAAA GGAC )在字母序列中,如果它们包含这些图案,我想得到该部分的id和序列。 但关键是 阿塔亚 应该是第一个序列 GGAC公司 在那之后会来的它们之间有一段距离,但这个距离可以是2个字母或更多。

预期产量:

>chr16:134222-134283
AGCTGGAAGCAGCGTGAATAAAACAGAATGGCCGGGACCTTAAAGGCTTTGCTTGGCCTGG

我尝试在python中使用以下命令执行此操作:

infile = open('infile.txt', 'r')
mot1 = 'AATAAA'
mot2 = 'GGAC'
new = []
for line in range(len(infile)):
    if not infile[line].startswith('>'):
        for match in pattern.finder(mot1) and pattern.finder(mot2):
            new.append(infile[line-1])


with open('outfile.txt', "w") as f:
    for item in new:
        f.write("%s\n" % item)

此代码不返回我想要的内容你知道怎么修吗?

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/48528
 
948 次点击  
文章 [ 5 ]  |  最新文章 4 年前
kantal
Reply   •   1 楼
kantal    5 年前

如果文件不太大,可以立即读取,并使用re.findall():

    import re
    with open("infile.txt") as finp:
        data=finp.read()
    with open('outfile.txt', "w") as f:
        for item in re.findall(r">.+?[\r\n\f][AGTC]*?AATAAA[AGTC]{2,}GGAC[AGTC]*", data):
            f.write(item+"\n")

"""
+? and *?       means non-greedy process;
>.+?[\r\n\f]    matches a line starting with '>' and followed by any characters to the end of the line; 
[AGTC]*?AATAAA  matches any number of A,G,T,C characters, followed by the AATAAA pattern; 
[AGTC]{2,}      matches at least two or more characters of A,G,T,C;
GGAC            matches the GGAC pattern;
[AGTC]*         matches the empty string or any number of A,G,T,C characters.
"""
Rachit Bhargava
Reply   •   2 楼
Rachit Bhargava    5 年前

如果 mot1 在里面找到的有一种方法:

from math import ceil

infile = open('infile.txt', 'r')
text = infile.readlines()
infile.close()

mot1 = 'AATAAA'
mot2 = 'GGAC'

check = [(text[x], text[x+1]) for x in range(ceil(len(text)/2))]

result = [(x + '\n' + y) for (x, y) in check if mot1 in y and mot2 in y[(y.find(mot1)+len(mot1)+2):]]

with open('outfile.txt', "w") as f:
    for item in result:
        f.write("%s\n" % item)
rahlf23
Reply   •   3 楼
rahlf23    5 年前

您可以使用regex和字典理解:

import re

with open('test.txt', 'r') as f:
    lines = f.readlines()
    data = dict(zip(lines[::2],lines[1::2]))

{k.strip(): v.strip() for k,v in data.items() if re.findall(r'AATAAA\w{2,}GGAC', v)}

返回:

{'>chr16:134222-134283': 'AGCTGGAAGCAGCGTGAATAAAACAGAATGGCCGGGACCTTAAAGGCTTTGCTTGGCCTGG'}
grapes
Reply   •   4 楼
grapes    5 年前

我不确定你对 this distance can be 2 letters or more ,是否必须进行检查,但以下代码将为您提供所需的输出:

mot1 = 'AATAAA'
mot2 = 'GGAC'

with open('infile.txt', 'r') as inp:
    last_id = None
    for line in inp:
        if line.startswith('>'):
            last_id = line
        else:
            if mot1 in line and mot2 in line:
                print(last_id)
                print(line)

如果需要,可以将输出重定向到文件

Ajax1234
Reply   •   5 楼
Ajax1234    5 年前

您可以将ID按顺序分组,然后利用 re.findall :

import re
data = [i.strip('\n') for i in open('filename.txt')]
new_data = [[data[i], data[i+1]] for i in range(0, len(data), 2)]
final_result = [[a, b] for a, b in new_data if re.findall('AATAAA\w{2,}GGAC', b)]

输出:

[['>chr16:134222-134283', 'AGCTGGAAGCAGCGTGAATAAAACAGAATGGCCGGGACCTTAAAGGCTTTGCTTGGCCTGG']]