我有一个巨大的文本文件(12GB)。这些行以制表符分隔,第一列包含ID。对于每个ID,我想做点什么。因此,我的计划是从第一行开始,逐行遍历第一列,直到达到下一个ID。
start_line = b
num_lines = 377763316
while b < num_lines:
plasmid1 = linecache.getline("Result.txt", b-1)
plasmid1 = plasmid1.strip("\n")
plasmid1 = plasmid1.split("\t")
plasmid2 = linecache.getline("Result.txt", b)
plasmid2 = plasmid2.strip("\n")
plasmid2 = plasmid2.split("\t")
if not str(plasmid1[0]) == str(plasmid2[0]):
end_line = b
#do something
代码有效,但问题是linecache似乎每次都重新加载txt文件。如果我不提高性能,代码将运行几年。
如果您对如何解决问题或了解其他方法有所了解,感谢您的帮助!
谢谢, 菲利普
答案 0 :(得分:0)
您应该只打开一次文件,然后遍历这些行。
with open('Result.txt', 'r') as f:
aline = f.next()
currentid = aline.split('\t', 1)[0]
for nextline in f:
nextid = nextline.split('\t', 1)[0]
if nextid != currentid:
#do stuff
currentid = nextid
你明白了,只需使用普通的python。
每次迭代只读取一行。拆分中的额外1
参数将仅拆分为第一个选项卡,从而提高性能。使用任何专用库都不会获得更好的性能。只有简单的C语言实现才能胜过这种方法。
如果你得到AttributeError: '_io.TextIOWrapper' object has
,可能是因为你使用的是Python 3.X(见问题io-textiowrapper-object)。请尝试使用此版本:
with open('Result.txt', 'r') as f:
aline = f.readline()
currentid = aline.split('\t', 1)[0]
while aline != '':
aline = f.readline()
nextid = aline.split('\t', 1)[0]
if nextid != currentid:
#do stuff
currentid = nextid
答案 1 :(得分:0)
我认为numpy.loadtxt()是要走的路。还可以通过usecols
参数来指定文件中实际需要的列。 Numpy软件包是以高性能为基础编写的实体库。
致电loadtxt()
后,您将获得ndarray。
答案 2 :(得分:0)
您可以使用itertools:
from itertools import takewhile
class EqualityChecker(object):
def __init__(self, id):
self.id = id
def __call__(self, current_line):
result = False
current_id = current_line.split('\t')[0]
if self.id == current_id:
result = True
return result
with open('hugefile.txt', 'r') as f:
for id in ids:
checker = EqualityChecker(id)
for line in takewhile(checker, f.xreadlines()):
do_stuff(line)
外部循环id
实际上可以从第一行获得,其id不匹配先前的值。