首页 > 解决方案 > 如何从python中的60GB文本文件中读取与特定行号相对应的数据?

问题描述

我有一个 60GB 大小的文本文件(10 亿行)。我必须提取与可以从另一个文本文件(例如:1、4、70、100...等)读取的指定行号相对应的数据。由于大小我无法将数据加载到内存然后提取行。此外,逐行匹配和提取需要很多天的时间。这个问题有解决方案吗?

我尝试过的2种方法:

1.第一种方法

f = open('line_numbers.txt')
lines = f.readlines()
numbers =[int(e.strip()) for e in lines]
r = max(numbers)
file = open('OUTPUT_RESULT.txt','w') 
with open('Large_File.txt') as infile:
        for num, line in enumerate(infile,1):
                if (num<= r):
                        if (num in numbers):
                                file.write(line)
                        else:
                                pass
                        print(num)

需要很多天才能得到结果

2.第二种方法

import pandas as pd
data = pd.read_csv('Large_File.txt', header=None)
file = open('OUTPUT_RESULT.txt','w') 

f = open('line_numbers.txt')
lines = f.readlines()
numbers =[int(e.strip()) for e in lines]

x = data.loc[numbers,:]
file.write(x)

它不会将文件加载到内存

有没有可用的解决方案来解决这个问题?

标签: pythonpython-3.x

解决方案


您的问题可能与if (num in numbers)线路有关。它不仅不需要括号,而且它还会在每次迭代时检查它,即使您的代码按顺序遍历文件(第一行,然后是第 2 行,等等)。

这可以很容易地优化,并且这样做,下面的代码在大约 5000 万行的测试文件上只运行了 12 秒。它应该在几分钟内处理您的文件。

import random

numbers = sorted([random.randint(1, 50000000) for _ in range(1000)])
outfile = open('specific_lines.txt', 'w')
with open('archive_list.txt', 'r', encoding='cp437') as infile:
    for num, line in enumerate(infile, 1):
        if numbers:
            if num == numbers[0]:
                outfile.write(line)
                print(num)
                del numbers[0]
            else:
                pass

注意:这会生成 1,000 个随机行号,替换为您的示例中加载的数字。如果您的数字列表要大得多,则输出文件的写入时间会稍微增加执行时间。

你的代码会是这样的:

with open('line_numbers.txt') as f:
    lines = f.readlines()
numbers = sorted([int(e.strip()) for e in lines])
outfile = open('specific_lines.txt', 'w')
with open('archive_list.txt', 'r', encoding='cp437') as infile:
    for num, line in enumerate(infile, 1):
        if numbers:
            if num == numbers[0]:
                outfile.write(line)
                print(num)
                del numbers[0]
            else:
                pass

推荐阅读