我需要使用Python从大型txt文件中提取N行数据。这些文件基本上是制表符分隔的表格。我的任务有以下限制:
- 这些文件可能包含标题(有些具有多行标题)。
- 标题需要按照相同的顺序出现在输出中。
- 每行只能被提取一次。
- 目前最大的文件约为150GB(约6000万行)。
- 在一个文件中,行大致相同长度,但在不同的文件中可能会有所不同。
- 通常我会提取5000个随机行(我可能需要高达100万行)
目前,我已经编写了以下代码:
inputSize=os.path.getsize(options.input)
usedPositions=[] #Start positions of the lines already in output
with open(options.input) as input:
with open(options.output, 'w') as output:
#Handling of header lines
for i in range(int(options.header)):
output.write(input.readline())
usedPositions.append(input.tell())
# Find and write all random lines, except last
for j in range(int(args[0])):
input.seek(random.randrange(inputSize)) # Seek to random position in file (probably middle of line)
input.readline() # Read the line (probably incomplete). Next input.readline() results in a complete line.
while input.tell() in usedPositions: # Take a new line if current one is taken
input.seek(random.randrange(inputSize))
input.readline()
usedPositions.append(input.tell()) # Add line start position to usedPositions
randomLine=input.readline() # Complete line
if len(randomLine) == 0: # Take first line if end of the file is reached
input.seek(0)
for i in range(int(options.header)): # Exclude headers
input.readline()
randomLine=input.readline()
output.write(randomLine)
这段代码似乎正常工作。
我知道这段代码更喜欢处理紧随输入中最长行后的行,因为seek()最有可能返回最长行的位置,并且下一行会被写入输出。但是,由于输入文件中的行大致相同长度,这与此无关。 此外,我知道如果N大于输入文件中的行数,这段代码会导致无限循环。我不会实施此检查,因为获取行数需要很长时间。
RAM和HDD的限制并不重要。我只关心程序的速度。是否有方法进一步优化此代码?或者也许有更好的方法吗?
编辑:澄清一下,一个文件中的行大致相同长度。但是,我有多个文件需要运行此脚本,每个文件的平均行长度都不同。例如,文件A的每行大约有100个字符,而文件B的每行大约有50000个字符。我不知道任何文件的平均行长度。