Python - 比较 2 个文件中的列并返回合并的输出
Python - comparing columns in 2 files and returning merged output
我有一个看似简单的问题,但现在已经困扰了太久。我想比较两个文件(格式如下)
> file1
20 246057 0.28 68363 0 A
20 246058 0.28 68396 T C
20 246059 0.28 76700 A G
20 246060 0.28 76771 T C
20 246061 0.28 76915 0 A
> file2
112879285 R 68303 20
200068921 M 68319 20
200257910 K 68336 20
200192457 W 68363 20
138777928 Y 68396 20
我想比较 file1 的第 0 列和第 3 列与 file2 的第 2 列和第 3 列,如果它们匹配,我想输出两个文件中匹配行的其余信息,如下所示:
> desired output
20 246057 0.28 68363 0 A 200192457 W
20 246058 0.28 68396 T C 138777928 Y
这是我到目前为止的代码,我已经尝试了这个代码的几个变体和这里的许多建议,但我仍然不知道如何从 file1 中获取相应的信息。我尝试的大多数事情都会导致每次匹配都重复 file1 中的最后一行。
#!/usr/bin/python
import csv
data2 = []
output = open("output.txt","w")
with open("file1.txt", "rb") as in_file1, open("file2.txt","rb") as in_file2:
reader1 = csv.reader((in_file1), delimiter="\t")
for row1 in reader1:
y1 = row1[0], row1[3]
data2.append(tuple(y1))
y = row1
reader2 = csv.reader((in_file2), delimiter="\t")
for row2 in reader2:
z = row2[-1], row2[2]
if tuple(z) in data2:
out = "\t".join(row2)
output.write(out+"\n")
我苦苦挣扎的部分是在解析后从 file1 获取输出。所以我目前以下面的结果结束,但我还想要 file1 中这些行的相应信息:
> current output
200192457 W 68363 20
138777928 Y 68396 20
非常感谢任何帮助或建议!谢谢! (我正在使用 python 2.7)
这是 join
, awk
, and cut
的一个很好的用例:
$ join -11 -24 file1 file2 | awk ' == { }' | cut -d' ' -f1-8
输出:
20 246057 0.28 68363 0 A 200192457 W
20 246058 0.28 68396 T C 138777928 Y
解释:
- 在第一个 (
-11
) 和第四个 (-24
) 字段上加入两个文件 file1
和 file2
。
- 仅过滤第 4 和第 9 字段相等的行 (
==
);打印这些行 ({ }
).
- 从这些行中仅打印第 1 到第 8 个字段 (
-f1-8
)。
尝试将您的代码修改为以下内容,您实际上需要存储您在文件 2 中获得匹配项的第 1 行:
with open("file1.txt", "rb") as in_file1, open("file2.txt","rb") as in_file2:
reader1 = csv.reader((in_file1), delimiter="\t")
for row1 in reader1:
y1 = row1[0], row1[3]
reader2 = csv.reader((in_file2), delimiter="\t")
for row2 in reader2:
z = row2[-1], row2[2]
if tuple(z) in [tuple(y1)]:
out = "\t".join(row1)
output.write(out+"\n")
out = "\t".join(row2)
output.write(out+"\n")
这是我从头开始编写的解决方案:
f1 = file("file1.txt")
f2 = file("file2.txt")
d = {}
while True:
line = f1.readline()
if not line:
break
c0,c1,c2,c3,c4,c5 = line.split()
d[(c0,c3)] = (c0,c1,c2,c3,c4,c5)
while True:
line = f2.readline()
if not line:
break
c0,c1,c2,c3 = line.split()
if (c3,c2) in d:
vals = d[(c3,c2)]
print c3,vals[1],vals[2],vals[3],vals[4],vals[5],c0,c1
它读取第一个文件,并使用 tuple
键将值存储到 dict
中。然后它读取第二个文件,并检查字典中是否存在 tuple
键。如果是,它会打印所有数据。
请注意,您还必须记住在程序的最终工作版本中也关闭这些文件。为简洁起见,我省略了关闭文件的行。
我有一个看似简单的问题,但现在已经困扰了太久。我想比较两个文件(格式如下)
> file1
20 246057 0.28 68363 0 A
20 246058 0.28 68396 T C
20 246059 0.28 76700 A G
20 246060 0.28 76771 T C
20 246061 0.28 76915 0 A
> file2
112879285 R 68303 20
200068921 M 68319 20
200257910 K 68336 20
200192457 W 68363 20
138777928 Y 68396 20
我想比较 file1 的第 0 列和第 3 列与 file2 的第 2 列和第 3 列,如果它们匹配,我想输出两个文件中匹配行的其余信息,如下所示:
> desired output
20 246057 0.28 68363 0 A 200192457 W
20 246058 0.28 68396 T C 138777928 Y
这是我到目前为止的代码,我已经尝试了这个代码的几个变体和这里的许多建议,但我仍然不知道如何从 file1 中获取相应的信息。我尝试的大多数事情都会导致每次匹配都重复 file1 中的最后一行。
#!/usr/bin/python
import csv
data2 = []
output = open("output.txt","w")
with open("file1.txt", "rb") as in_file1, open("file2.txt","rb") as in_file2:
reader1 = csv.reader((in_file1), delimiter="\t")
for row1 in reader1:
y1 = row1[0], row1[3]
data2.append(tuple(y1))
y = row1
reader2 = csv.reader((in_file2), delimiter="\t")
for row2 in reader2:
z = row2[-1], row2[2]
if tuple(z) in data2:
out = "\t".join(row2)
output.write(out+"\n")
我苦苦挣扎的部分是在解析后从 file1 获取输出。所以我目前以下面的结果结束,但我还想要 file1 中这些行的相应信息:
> current output
200192457 W 68363 20
138777928 Y 68396 20
非常感谢任何帮助或建议!谢谢! (我正在使用 python 2.7)
这是 join
, awk
, and cut
的一个很好的用例:
$ join -11 -24 file1 file2 | awk ' == { }' | cut -d' ' -f1-8
输出:
20 246057 0.28 68363 0 A 200192457 W
20 246058 0.28 68396 T C 138777928 Y
解释:
- 在第一个 (
-11
) 和第四个 (-24
) 字段上加入两个文件file1
和file2
。 - 仅过滤第 4 和第 9 字段相等的行 (
==
);打印这些行 ({ }
). - 从这些行中仅打印第 1 到第 8 个字段 (
-f1-8
)。
尝试将您的代码修改为以下内容,您实际上需要存储您在文件 2 中获得匹配项的第 1 行:
with open("file1.txt", "rb") as in_file1, open("file2.txt","rb") as in_file2:
reader1 = csv.reader((in_file1), delimiter="\t")
for row1 in reader1:
y1 = row1[0], row1[3]
reader2 = csv.reader((in_file2), delimiter="\t")
for row2 in reader2:
z = row2[-1], row2[2]
if tuple(z) in [tuple(y1)]:
out = "\t".join(row1)
output.write(out+"\n")
out = "\t".join(row2)
output.write(out+"\n")
这是我从头开始编写的解决方案:
f1 = file("file1.txt")
f2 = file("file2.txt")
d = {}
while True:
line = f1.readline()
if not line:
break
c0,c1,c2,c3,c4,c5 = line.split()
d[(c0,c3)] = (c0,c1,c2,c3,c4,c5)
while True:
line = f2.readline()
if not line:
break
c0,c1,c2,c3 = line.split()
if (c3,c2) in d:
vals = d[(c3,c2)]
print c3,vals[1],vals[2],vals[3],vals[4],vals[5],c0,c1
它读取第一个文件,并使用 tuple
键将值存储到 dict
中。然后它读取第二个文件,并检查字典中是否存在 tuple
键。如果是,它会打印所有数据。
请注意,您还必须记住在程序的最终工作版本中也关闭这些文件。为简洁起见,我省略了关闭文件的行。