python - 如何根据序列中的大写字母提取起始和结束位点?

标签 python sequence bioinformatics extract

我想提取大写字母的起始和结束站点信息。使用下面的代码计算序列长度并不能准确返回序列信息。给定起始站点时,我需要处理的 P 匹配结果基于第一个字母表,但我实际需要的起始站点是每个站点中出现的第一个大写字母。如何检索准确的起始站点和结束站点?谁能帮我吗?

文本文件A.txt

Scanning sequence ID:   BEST1_HUMAN

          150 (-)  1.000  0.997  GGAAAggccc                                   R05891
          354 (+)  0.988  0.981  gtgtAGACAtt                                  R06227
V$CREL_01c-RelV$EVI1_05Evi-1

Scanning sequence ID:   4F2_HUMAN

          365 (+)  1.000  1.000  gggacCTACA                                   R05884
           789 (-)  1.000  1.000  gcgCGAAA                                       R05828; R05834; R05835; R05838; R05839
V$CREL_01c-RelV$E2F_02E2F

预期输出:

序列ID开始结束

BEST1_HUMAN 150 155
BEST1_HUMAN 358 363
4F2_HUMAN   370 370
4F2_HUMAN   792 797

文件 B.txt

Scanning sequence ID: hg17_ct_ER_ER_142

              512 (-)  0.988  0.981  taTAGCTaagc                        Evi-1          R06227
V$EVI1_05

Scanning sequence ID: hg17_ct_ER_ER_1

              213 (-)  1.000  0.989  aggggcaggGGTCA                     COUP-TF, HNF-4 R07445
V$COUP_01

预期输出:

hg17_ct_ER_ER_142 514 519
hg17_ct_ER_ER_1 222 227

示例代码:

output_file = open('output.bed','w')
with open('A.txt') as f:
    text = f.read()
    chunks = text.split('Scanning sequence ID:')
    for chunk in chunks:
        if chunk:
            lines = chunk.split('\n')
            sequence_id = lines[0].strip()
            for line in lines:
                if line.startswith('              '):
                    start = int(line.split()[0].strip())
                    sequence = line.split()[-2].strip()
                    stop = start + len(sequence)
                    #print sequence_id, start, stop
                    seq='%s\t%i\t%i\n' % \
                         (sequence_id,start,stop)
                    output_file.write(seq)
output_file.close()

最佳答案

此代码将获取标签和起始值:

import re

p = "Scanning sequence ID\:\s*(?P<label>[A-Z0-9]+\_[A-Z0-9]+).*?(?P<start_value>\d+)"

with open("A.txt", "r") as f:
    s = f.read()

re.findall(p,s, re.DOTALL)

示例输出:

[('BEST1_HUMAN', '150'), ('4F2_HUMAN', '365')]

然后是第二个数字(“结束站点”)的计算。在开篇文章的代码中,我看到: sequence = line.split()[-2].strip();停止=开始+ len(序列)。因此,我得出的结论是,您希望使用倒数第二列的字符串长度(GGAAAggccc 等)来增加值 start

我也可以使用以下修改后的正则表达式捕获该列:

p = "Scanning sequence ID\:\s*(?P<label>[A-Z0-9]+\_[A-Z0-9]+).*?(?P<start_value>\d+)\s+\S+\s+\S+\s+\S+\s+(?P<sequence>\S+)"
re.findall(p,s, re.DOTALL)

示例输出:

[('BEST1_HUMAN', '150', 'GGAAAggccc'), ('4F2_HUMAN', '365', 'gggacCTACA')]

现在我们要处理一个标签有多个数据行的情况。为此,我们需要删除 re.findall 并进行迭代:

import re
with open("A.txt", "r") as f:
    lines = f.readlines()

label_ptrn = re.compile("^Scanning sequence ID\\:\\s*(?P<label>[A-Z0-9]+\\_[A-Z0-9]+)$")
line_ptrn = re.compile("^\s+(?P<start_value>\\d+)\\s+\\S+\\s+\\S+\\s+\\S+\\s+(?P<sequence>\\S+).*$")
inner_ptrn = re.compile("[A-Z]+")

all_matches = []
for line in lines:
    m = label_ptrn.match(line)
    if m:
        label = m.groupdict().get("label")
        continue
    m = line_ptrn.match(line)
    if m:
        start = m.groupdict().get("start_value")
        sequence = m.groupdict().get("sequence")
        mi = inner_ptrn.search(sequence)
        if not mi:
            continue
        span = mi.span()
        all_matches.append((label, int(start)+span[0], int(start)+span[1]))

然后您可以按如下方式打印匹配项:

with open("output.bed", "w+b") as f:
    for m in all_matches:
        f.write('%s\t%i\t%i\n' % m)

示例输出:

BEST1_HUMAN 150 155
BEST1_HUMAN 358 363
4F2_HUMAN   370 375
4F2_HUMAN   792 797

我认为问题已经解决了;)

关于python - 如何根据序列中的大写字母提取起始和结束位点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30931708/

相关文章:

python - random.random 到底在做什么

python - 对称字典,其中 d[a][b] == d[b][a]

python - 在 pythonanywhere 上从源代码安装工具

python - 一侧填充太慢的两个三维数组的卷积

python - 如何在 vscode 中设置 matplotlib 后端

ruby-on-rails - 在 rails 迁移期间如何避免 id 字段上的隐式序列

sql - 如何为每批新插入的行使用新的序列号?

algorithm - 序列 3,0,1,6,7 中的下一个数字是什么?以及如何将此序列编码为 n 位数字?

python - Snakemake PICARD合并bam文件

python - 如何在 PyPy 上使用 Biopython?