Best way to read a very large file in Python
我有一个100GB的文本文件,大约有50K行,长度不同。
它太大,内存不足,所以我现在一行一行地读。这也需要很长时间。有没有更聪明的方法来读取文件?例如,一次读几行?
- 对于这个大小的文件,我认为更重要的问题是"在读取数据时,您在做什么?"而不是如何阅读。
- 当你说"花的时间太长"时,你需要看看开销在哪里。你已经假设是IO在减慢速度,你也许是对的,但是如果没有看到代码,就不可能说出来。
- 你必须一行一行地读吗?你只需拿出你能合理处理的最大数量就可以了。
- @AKX:我将每一行转换为稀疏向量,然后将其添加到另一个numpy向量。
- 刚检查过,用io.FileIO代替open,速度提高了25倍以上。
- 所以numpy向量越来越大。那可能不是开销所在吗?
- @贝雷亚尔:那是使用和OP使用的相同版本的python吗?
- @努法利布拉欣:我需要台词,我一次可以有几个台词
- 首先分析您的代码。然后进行优化。
- @abarnethere为这个问题提供了一个很好的答案。
- @不好意思,我撤销了我的评论,我的评价是错误的。
- "添加到另一个向量"是指矢量和还是附加它?
- 一次可以读几行。f.readlines(16384)将读取16K,并将其作为行列表返回。有关readlines功能,请参见文档。这很少有什么区别,因为无论如何,python已经在缓冲读操作了,但是尝试并测试它是否有帮助并不难。
- 另外,您使用的是哪一个版本的python?这都是ASCII码,大部分是ASCII码,还是两者都不是?例如,如果您使用的是python 3.2,那么升级到3.4应该会有所帮助。或者,如果它都是ASCII码,而您无法升级,那么以二进制模式打开应该会有所帮助。
像这样的文件行的基本迭代:
1 2 3
| with open(filename) as f:
for line in f:
do_stuff(line) |
这实际上只将当前行读取到内存中,而不是更多。如果您想对缓冲区大小进行细粒度控制,我建议您改用io.open(例如,当您的行的长度相同时,这可能会很有用)。
如果数据上的操作实际上不是IO绑定的,而是CPU绑定的,那么使用多处理可能很有用:
1 2 3 4 5 6
| import multiprocessing
pool = multiprocessing.Pool(8) # play around for performance
with open(filename) as f:
pool.map(do_stuff, f) |
这不会加快实际的读取速度,但可能会提高处理行的性能。
- 这里多处理的使用很大程度上取决于问题是I/O还是CPU限制。
- 是的,这就是我在回答中提到它的原因。
- 谢谢。但不幸的是,我的线条长度不一样。
- @罗伊,多重处理可能对你有很大帮助。
- @罗伊,这和这个答案的有效性有什么矛盾?
- @constantinius Poll()是否获取文件指针的锁?
- for line in f:不一定一次只读取一行到内存中。
- @?Ukaszr.:不是。Pool.map采用任何形式的iterator,而file恰好是其中之一。所以主进程(创建池的进程)读取这些行,将它们发送到子进程并收集结果。
- @当然,它是:docs.python.org/2/tutorial/…
- @康斯坦提尼乌斯,不,没有。你链接的页面没有提到任何关于for line in f:的内容,一次只在内存中读取一行。它只是说它有记忆效率。它所能做的就是读取字节块并一次返回一行。更多信息请参见[此处]。
- @提格霍克特3:你的链接似乎丢失了。很可能它读的不止一行。我猜剩下的会有缓冲。既然op似乎想读取整个文件,那就没什么区别了,对吧?
- 很抱歉。链接这里。