我有两个文件,其中一个我有一个loci列表(Loci.txt
)(确切地说大约是1600万)而在第二个文件中我有一个行号列表({{1} })。我想要做的是只将Pos.txt
文件中指定的Loci.txt
中的行写入新文件。下面是两个文件的截断版本:
Loci.txt
Pos.txt
Pos.txt
R000001 1
R000001 2
R000001 3
R000001 4
R000001 5
R000001 6
R000001 7
R000001 8
R000001 9
R000001 10
这是我为任务编写的代码
1
3
5
9
10
代码与我想要的完全一样,输出看起来像这样
OUT.txt
#!/usr/bin/env python
import os
import sys
F1 = sys.argv[1]
F2 = sys.argv[2]
F3 = sys.argv[3]
File1 = open(F1).readlines()
File2 = open(F2).readlines()
File3 = open(F3, 'w')
Lines = []
for line in File1:
Lines.append(int(line))
for i, line in enumerate(File2):
if i+1 in Lines:
File3.write(line)
问题在于,当我将这个应用到我的整个数据集中时,我必须从包含1600万行的文件中提取大约1300万行,这需要永远完成。反正我是否可以编写这段代码以便它运行得更快?
答案 0 :(得分:1)
您的代码很慢,主要是因为您要在列表中搜索必须打印的行:if i+1 in Lines
。每次程序扫描完整列表以查找行号是否有效
你可以替换:
Lines = []
for line in File1:
Lines.append(int(line))
人:
Lines = {}
for line in File1:
Lines[int(line)] = True
答案 1 :(得分:0)
您可以尝试这样的事情:
import sys
F1 = sys.argv[1]
F2 = sys.argv[2]
F3 = sys.argv[3]
File1 = open(F1)
File2 = open(F2)
File3 = open(F3, 'w')
for linenumber in File2:
for line in File1:
if linenumber in line:
File3.write(line)
break
由于嵌套的for循环,这可能看起来很糟糕,但由于我们在文件的行上进行迭代,因此脚本将在发现最后一行时从它停止的地方继续。这是因为文件读取的工作原理,指针用于跟踪文件中的位置。为了再次从文件的开头读取,您必须使用 seek 函数将指针移动到文件的开头。
答案 2 :(得分:0)
您可以尝试使用以下代码:
#!/usr/bin/env python
with open("loci.txt") as File1:
lociDic = {int(line.split()[1]): line.split()[0] for line in File1}
with open("pos.txt") as File2:
with open("result.txt", 'w') as File3:
for line in File2:
if int(line) in lociDic:
File3.write(' '.join([lociDic[int(line)], line]))
此解决方案的关键点是:
我也使用File1和File2中包含的整数(代码),因为我认为File1序列中可能存在漏洞。否则其他解决方案也是可能的。
答案 3 :(得分:0)
正如其他人所提到的,首先在内存中读取整个文件是造成问题的原因。这是一种替代方法,它扫描大文件并仅写出匹配的那些行。
with open('search_keys.txt', 'r') as f:
filtered_keys = [line.rstrip() for line in f]
with open('large_file.txt', 'r') as haystack, open('output.txt', 'w') as results:
for line in haystack:
if len(line.strip()): # This to skip blanks
if line.split()[1] in filtered_keys:
results.write('{}\n'.format(line))
这样你一次只读取一行大文件并同时写出结果。
请记住,这不会对输出进行排序。
如果您的search_keys.txt
文件非常大,将filtered_keys
转换为set
会缩短查找时间。