根据重叠位置合并多条线路的信息

时间:2016-10-21 20:52:55

标签: python string bioinformatics

我希望根据具体情况组合多行信息。

这是我的输出:

ATAT 0 2 2
TATA 1 3 2
ATAT 2 4 2
TATA 3 5 2
GGGG 7 9 2
CCCC 11 13 2
GGGG 32 34 2

第一列是子串,
第二列是较大字符串中子字符串的起始位置,
第三列是子串的结束位置,
第四列是子串内2个字符单元的数量(ATAT有两个单位“AT”)。

我的目标是组合相邻的子串并输出新的子串,位置和总和。例如,在上面的输出中,有两种相邻的“ATAT”情况(第1和第3行)。我们知道它们是相邻的,因为第一个ATAT的结束位置是第二个“ATAT”的起始位置。 所以我想要的输出看起来像:

ATATATAT 0 4 4
TATATATA 1 5 4
GGGG 7 9 2
CCCC 11 13 2
GGGG 32 34 2

请注意,每个字符串的新位置是遇到的第一个字符串的起始位置和遇到的最后一个字符串的结束位置。

我的预感是,这可以通过以下方式完成 1)制作这些值的字典,使得(ATAT:0,2,2)
2)迭代原始文件并拉出子串匹配的实例,其中一个的开头等于另一个的结束,
3)将求和的+连接结果打印到新文件。

然而,这似乎相当不优雅。有没有更有效的方法来实现这一目标?谢谢。

编辑:@cdlane,当使用下面的输入和脚本时(调整为处理逗号分隔符): INPUT:

AT,0,2
TA,1,3
AT,2,4
TA,3,5
AT,4,6
TA,5,7
AG,6,8
GG,7,9
GG,8,10
GG,9,11
GC,10,12
CC,11,13
CC,12,14
CC,13,15
CG,14,16
GC,15,17
CT,16,18
TG,17,19
GC,18,20
CT,19,21
TG,20,22
GA,21,23
AC,22,24
CG,23,25
GG,24,26
GA,25,27
AC,26,28
CG,27,29
GT,28,30
TT,29,31
TT,30,32
TG,31,33
GG,32,34
GG,33,35
GG,34,36

输出:
     ('ATAT','0','4')
    ('TATA','1','5')     ('GC','10','12')     ('CCCC','11','15')     ('CC','12','14')     ('CG','14','16')     ('GC','15','17')     ('CT','16','18')     ('TG','17','19')     ('GC','18','20')     ('CT','19','21')     ('TG','20','22')     ('GA','21','23')     ('AC','22','24')     ('CG','23','25')     ('GG','24','26')     ('GA','25','27')     ('AC','26','28')     ('CG','27','29')     ('GT','28','30')     ('TT','29','31')     ('TT','30','32')     ('TG','31','33')     ('GGGG','32','36')     ('GG','33','35')     ('AT','4','6')
    ('TA','5','7')     ('AG','6','8')     ('GGGG','7','11')
    ('GG','8','10')

1 个答案:

答案 0 :(得分:0)

如果(修订的)输入表现良好(排序,没有重叠等),那么我们应该能够结合两个主循环,并通过使结束位置成为键来消除迭代期间的删除。检查每个起始位置是否在字典中:

import sys

dictionary = dict()

with open(sys.argv[1]) as source:
    for line in source:
        substring, start, end = line.rstrip().split(",")

        start = int(start)
        units = len(substring) // 2

        if start in dictionary:
            ext_substring, ext_start, ext_units = dictionary[start]

            if substring * ext_units == ext_substring:
                del dictionary[start]
                substring += ext_substring
                start = ext_start
                units += ext_units

        dictionary[int(end)] = (substring, start, units)

for end in sorted(dictionary, key=lambda key: dictionary[key][1]):
    substring, start, units = dictionary[end]
    print(substring, start, end, units, sep=",")

这给出了输出:

ATATAT,0,6,3
TATATA,1,7,3
AG,6,8,1
GGGG,7,11,2
GG,8,10,1
GC,10,12,1
CCCC,11,15,2
CC,12,14,1
CG,14,16,1
GC,15,17,1
CT,16,18,1
TG,17,19,1
GC,18,20,1
CT,19,21,1
TG,20,22,1
GA,21,23,1
AC,22,24,1
CG,23,25,1
GG,24,26,1
GA,25,27,1
AC,26,28,1
CG,27,29,1
GT,28,30,1
TT,29,31,1
TT,30,32,1
TG,31,33,1
GGGG,32,36,2
GG,33,35,1

此输入令人不安,因为它表示重叠,其处理尚未讨论:

GG,32,34
GG,33,35
GG,34,36