我有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)
答案 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))