在Python中高效读取数据的方法

4 投票
2 回答
3885 浏览
提问于 2025-04-16 15:03

可能重复的问题:
在Python中读取大文件的懒惰方法?

我需要从一个文件中逐行读取100GB(4亿行)的数据。这是我现在的代码,但有没有更高效的方法来做到这一点?我指的是执行速度方面。

f = open(path, 'r')

for line in f: 
    ...

f.close()

2 个回答

2

如果每行的字节长度是固定的,并且这些行不需要按照特定的顺序读取(你还是可以知道行号),那么你可以很容易地把这个任务分成多个小任务,使用多个线程或进程来同时执行。每个小任务只需要知道从哪里开始读取(也就是用seek()),以及要读取多少字节(用read())。

在这种情况下,逐行读取并不是最优的做法,因为这样需要去查找\n(换行符),不如直接使用read()来读取固定长度的数据。

2

如果你有一台多核的电脑,并且可以使用Python 3.2(而不是Python 2),那么可以考虑使用Python 3.2的新功能concurrent.futures来处理一些任务,这样做是很合适的——具体取决于你对每一行需要做什么处理。如果你需要按照文件的顺序来处理这些内容,那你可能还得担心后面怎么把结果重新整理回来。

否则,使用concurrent.futures可以很轻松地把每个客户端的处理安排到不同的任务中去。你需要生成什么样的输出呢?

如果你觉得把每一行的内容并行处理没有什么好处,那么最简单的方法就是继续按照你现在的做法来进行处理。

这个例子把处理分成了最多12个子进程,每个子进程执行Python内置的len函数。你可以把len替换成一个接收行作为参数并执行你需要处理的函数:

from concurrent.futures import ProcessPoolExecutor as Executor

with Executor(max_workers=5) as ex:
    with open("poeem_5.txt") as fl:
       results = list(ex.map(len, fl))

这里的“list”调用是为了确保在“with”语句中完成映射。如果你不需要每一行的标量值,而是想把结果记录到一个文件中,你可以用一个for循环来实现:

for line in fl:
   ex.submit(my_function, line)

撰写回答