处理速度 - 编辑大型2GB文本文件python

时间:2013-10-20 18:03:39

标签: python performance text

所以我有一个问题。我正在使用.txt文件,这些文件由4行多个组成。我在python 3工作。

我编写了一个代码,用于获取文本文件的每个第2行和第4行,并仅保留这两行的前20个字符(同时保留第1行和第3行未编辑),并创建一个新的编辑文件,包括编辑的第2和第4行以及未经编辑的第1和第3行。由于我使用的所有文本文件的行号始终是4的倍数,因此每个行的趋势都是相同的。

这适用于小文件(总共约100行),但我需要的文件是5000万+行,需要4个多小时。

以下是我的代码。谁能给我一个关于如何加快我的计划的建议?谢谢!

import io
import os
import sys

newData = ""
i=0
run=0
j=0
k=1
m=2
n=3
seqFile = open('temp100.txt', 'r')
seqData = seqFile.readlines()
while i < 14371315:
    sLine1 = seqData[j] 
    editLine2 = seqData[k]
    sLine3 = seqData[m]
    editLine4 = seqData[n]
    tempLine1 = editLine2[0:20]
    tempLine2 = editLine4[0:20]
    newLine1 = editLine2.replace(editLine2, tempLine1)
    newLine2 = editLine4.replace(editLine4, tempLine2)
    newData = newData + sLine1 + newLine1 + '\n' + sLine3 + newLine2
    if len(seqData[k]) > 20:
         newData += '\n'
    i=i+1
    run=run+1
    j=j+4
    k=k+4
    m=m+4
    n=n+4
    print(run)

seqFile.close()

new = open("new_100temp.txt", "w")
sys.stdout = new
print(newData)

4 个答案:

答案 0 :(得分:2)

您正在使用内存中的两个文件(输入和输出)。如果文件很大(分页),它可能会导致时间问题。尝试(伪代码)

Open input file for read
Open output file for write
Initialize counter to 1
While not EOF in input file
    Read input line
    If counter is odd 
        Write line to output file
    Else
        Write 20 first characters of line to output file
    Increment counter
Close files

答案 1 :(得分:2)

这里最大的问题似乎是一次读取整个文件:

seqData = seqFile.readlines()

相反,您应首先打开源文件和输出文件。然后迭代第一个文件并按照您的意愿操作这些行:

outfile = open('output.txt', 'w')
infile = open('input.txt', 'r')

i = 0
for line in infile:
    if i % 2 == 0:
       newline = line
    else:
       newline = line[:20]

    outfile.write( newline )
    i += 1

outfile.close()
infile.close()

答案 2 :(得分:2)

如果您一次只读4行并处理(未经测试),则可能会快得多:

with open('100temp.txt') as in_file, open('new_100temp.txt', 'w') as out_file:
    for line1, line2, line3, line4 in grouper(in_file, 4):
         # modify 4 lines
         out_file.writelines([line1, line2, line3, line4])

其中grouper(it, n)是一次生成nit项的函数。它是itertools模块的examples之一(另请参阅SO中的this anwer)。以这种方式迭代文件类似于在文件上调用readlines(),然后手动迭代结果列表,但它一次只能读入几行内存。

答案 3 :(得分:1)

有关阅读文件的最佳方法,请参阅docs。而不是将它全部保存在内存中,这就是你正在使用seqData = seqFile.readlines()进行的操作,而只是遍历。 Python负责缓冲等。为了你,所以它快速有效。此外,您不应自己打开和关闭文件(如其他答案) - 使用with关键字。

lineCount = 0
with open("new_100temp.txt", "w") as newFile, open("100temp.txt","r") as oldFile:
    for line in oldFile:
        #start on line 1, keep 1st and 3rd as is, modify 2nd and 4th
        lineCount += 1
        if lineCount%4 == 1 or lineCount%4 == 3: 
            newFile.write(line)
        else:
            newFile.write(line[:20] + "\n")
            # printing is really slow, so only do it every 100th iteration:
        if lineCount % 100 == 0:
            print lineCount

我只是尝试了一百万行垃圾文本,并在不到一秒的时间内完成了它。正如Kevin所说,像这样的简单文本作业对于shell来说是有好处的。