Python - 如何读取文本文件中的特定行?

时间:2017-02-25 18:16:32

标签: python text readline

我有一个巨大的文本文件(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文件。如果我不提高性能,代码将运行几年。

如果您对如何解决问题或了解其他方法有所了解,感谢您的帮助!

谢谢, 菲利普

3 个答案:

答案 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不匹配先前的值。