在python中总结2个文本文件

时间:2018-10-25 21:09:49

标签: python

我有2个大文本文件,例如以下小示例。有两个文件(主要和次要)。在主要和次要文件中都有4列。在主文件中,第二列和第三列之间的差异为10000,第二列和第三列之间的差异为32或31或接近31的数字,但不是很高。

主要文件的小示例:

chr4    530000  540000  0.0
chr4    540000  550000  1719.0
chr4    550000  560000  0.0

次要文件的小示例:

chr4    295577  295608  12
chr4    323326  323357  10
chr4    548873  548904  32
chr4    548873  548904  20
chr4    549047  549078  32
chr4    549047  549078  20
chr4    549137  549168  32
chr4    549137  549168  20
chr4    549181  549212  32
chr4    549181  549212  20
chr4    549269  549300  22
chr4    549269  549300  381
chr4    549269  549300  67
chr4    549269  549300  89
chr4    549269  549300  95
chr4    549269  549300  124
chr4    549269  549300  149
chr4    549269  549300  87
chr4    549269  549300  33
chr4    549269  549300  65
chr4    549269  549300  68
chr4    549269  549300  190
chr4    549269  549300  20
chr4    549355  549386  32
chr4    549355  549386  20
chr4    549443  549474  16
chr4    705810  705841  10
chr4    846893  846924  28

我想创建一个新的文本文件,其中会有4列。像预期的输出一样:

chr4    548873  548904  32  chr4    540000  550000
chr4    548873  548904  20  chr4    540000  550000
chr4    549047  549078  32  chr4    540000  550000
chr4    549047  549078  20  chr4    540000  550000
chr4    549137  549168  32  chr4    540000  550000
chr4    549137  549168  20  chr4    540000  550000
chr4    549181  549212  32  chr4    540000  550000
chr4    549181  549212  20  chr4    540000  550000
chr4    549269  549300  22  chr4    540000  550000
chr4    549269  549300  381 chr4    540000  550000
chr4    549269  549300  67  chr4    540000  550000
chr4    549269  549300  89  chr4    540000  550000
chr4    549269  549300  95  chr4    540000  550000
chr4    549269  549300  124 chr4    540000  550000
chr4    549269  549300  149 chr4    540000  550000
chr4    549269  549300  87  chr4    540000  550000
chr4    549269  549300  33  chr4    540000  550000
chr4    549269  549300  65  chr4    540000  550000
chr4    549269  549300  68  chr4    540000  550000
chr4    549269  549300  190 chr4    540000  550000
chr4    549269  549300  20  chr4    540000  550000
chr4    549355  549386  32  chr4    540000  550000
chr4    549355  549386  20  chr4    540000  550000
chr4    549443  549474  16  chr4    540000  550000

前4列来自次要文件,后3列来自主文件。

第2列和第3列(来自次要文件)中的数字在同一行的范围内,但第6列和第7列(来自主要文件)和第1列的数字等于第5列(实际上是第1列)主要文件和次要文件)。

我要查找次要文件中的行,其中第一列等于主文件的第一列,同一行(次要文件中)的第二列和第三列也必须在第二个和第二个范围内主文件中的第三列。

因此,实际上,次要文件中的每一行都有3个条件可以包含在输出文件中。

最后3列来自主要文件,适合次要文件中的行。

我正在尝试使用Python进行此操作,并编写了以下代码,但未返回我期望的结果:

major = open("major.txt", 'rb')
minor = open("minor.txt", 'rb')
major_list = []
minor_list = []
for m in major:
    major_list.append(m)

for n in minor:
    minor_list.append(n)

final = []
for i in minor_list:
    for j in major_list
        if minor_list[i] == major_list[j] and minor_list[i+1] <= major_list[j+1] and minor_list[i+2] >= major_list[j+2]:
        final.append(i)


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

3 个答案:

答案 0 :(得分:2)

我不确定代码是否完全符合您的目标,因此我可能已经更改了一些您必须改回来的内容,但这应该有所帮助-下面的代码输出所需的输出。 / p>

major = open("major.txt", "r")
minor = open("minor.txt", "r")
major_list = []
minor_list = []
for m in major:
    major_list.append(m)

for n in minor:
    minor_list.append(n)

final = []
for i in range(0, len(minor_list)):  # to iterate using the index
    for j in range(0, len(major_list)):

        minor_row = minor_list[i]
        major_row = major_list[j]

        minor_columns = minor_row.split()
        major_columns = major_row.split()

        minor_symbol = minor_columns[0]
        major_symbol = major_columns[0]

        if minor_symbol == major_symbol:
            minor_second_col = int(minor_columns[1])
            minor_third_col = int(minor_columns[2])
            min_range = int(major_columns[1])
            max_range = int(major_columns[2])

            if (minor_second_col <= max_range and minor_second_col >= min_range
                and minor_third_col <= max_range and minor_third_col >= min_range):
                new_line = minor_row.rstrip("\n") + " " + str(major_symbol) + " " + str(min_range) + " " + str(max_range)
                final.append(new_line)


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

您正在迭代这些行并将行彼此比较-

m in major:

split()函数将空格分隔的行的字符串断开,并在字符串列表中返回结果。查看str.split的文档,我认为这会有所帮助。

答案 1 :(得分:2)

这些是.bed文件,而您想要做的就是称为交集。

如果您使用的是Linux或Mac,或者可以访问它,则可以安装bedtools,这样做很值得,因为您可以在一行代码中完成所有这些操作:

bedtools intersect -wa -wb -a minor_file -b major_file > new_text_file

实际上,区间交点正是开发床具的原因。

有一个叫做'pybedtools'的bedtools python发行版,但是它也仅适用于mac和linux,所以我认为在Python中这样做没有太大的优势。

您当然可以使用Python进行所有操作,但是如果您要进行任何数量的生物信息学研究,那么基础工具和GATK(来自Broad Institute的基因组分析工具套件,仅适用于命令行界面)是有充分理由的在shell中做一些事情。另外,您需要在某个时间点对间隔进行排序,以便进行下游操作,并且不会永远花费时间。为此,使用shell命令“ sort”太快了(sort -k1,1V -k2,2n -k3,3n [your_file]> [new_sorted_file])。

但是GATK和基础工具中的基因组特定工具(需要索引基因组序列文件的工具)是在shell中执行某些操作的重要原因。与bedtools intersect命令类似,在Python中实现该功能将需要编写和调试许多代码行,并且这些代码的运行比仅在bedtools和GATK中调用适当的命令要慢得多。

答案 2 :(得分:0)

您好,从我对您的逻辑的理解来看,我认为下面的代码应该带给您正确的指导,希望对您有所帮助。

import re

# read in files
with open("major.txt") as f:
    major = [x.strip("\n") for x in f.readlines()]

with open("minor.txt") as f:
    minor = [x.strip("\n") for x in f.readlines()]

# split into list of lists
p = re.compile(" +")
major = list(map(lambda x: p.split(x), major))
minor = list(map(lambda x: p.split(x), minor))

with open("output.txt", "w") as out:
    # uses the fact that the lists of lists contain 4 ite
    for major_col1, major_col2, major_col3, major_col4 in major:
        for minor_col1, minor_col2, minor_col3, minor_col4 in minor:
            if major_col1 == minor_col1:
                if int(major_col2) < int(minor_col2) and \
                   int(major_col2) < int(minor_col3) and \
                   int(major_col3) > int(minor_col2) and \
                   int(major_col3) > int(minor_col3):
                   out.write("{0:<10} {1:^8} {2:^8} {3:<8} {4:<10} {5:^8} {6:^}\n"
                             .format(minor_col1, minor_col2,
                                     minor_col3, minor_col4,
                                     major_col1, major_col2, 
                                     major_col3))