在Python中使用多个大文件

时间:2014-06-27 08:38:03

标签: python python-3.x

我有大约60个文件,每个文件包含大约900000行,每行是17个制表符分隔的浮点数。每行我需要使用来自所有60个文件的所有相应行进行一些计算,但由于它们的大尺寸(每个文件大小为400 MB)和有限的计算资源,它需要很长时间。我想知道有什么办法可以快速完成吗?

3 个答案:

答案 0 :(得分:1)

这取决于你如何处理它们。如果你有足够的内存,你可以先读取所有文件,然后将它们更改为python数据结构。然后你可以做计算。

如果您的文件不适合内存,最简单的方法是使用一些分布式计算机制(hadoop或其他更轻的替代品)。

另一个较小的改进可能是使用fadvice linux函数调用来说明你将如何使用该文件(顺序读取或随机访问),它告诉操作系统如何优化文件访问。

如果计算适合某些常见的库,如numpy numexpr,它们有很多优化,你可以使用它们(如果你的计算使用未经过优化的算法来处理它们,这会有所帮助)。

答案 1 :(得分:1)

如果“对应行”表示“所有文件的第一行,然后是所有文件的第二行等”,则可以使用`itertools.izip:

# cat f1.txt
1.1
1.2
1.3

# cat f2.txt
2.1
2.2
2.3

# python
>>> from itertools import izip
>>> files = map(open, ("f1.txt", "f2.txt"))
>>> lines_iterator = izip(*files)
>>> for lines in lines_iterator:
...     print lines
...
('1.1\n', '2.1\n')
('1.2\n', '2.2\n') 
('1.3\n', '2.3\n')
>>>

答案 2 :(得分:0)

一些选择:

<强> 1。只需使用内存

如果您有17x900000 = 15.3 M浮点/文件。将其存储为双精度(通常为numpy)将为每个文件占用大约120 MB的内存。您可以通过将浮点数存储为float32来减少这种情况,这样每个文件大约需要60 MB。如果您有60个文件和60 MB /文件,则您拥有3.6 GB的数据。

如果您使用64位python,则此数量并非不合理。如果您的计算机中的RAM少于6 GB,则会导致大量虚拟内存交换。这是否是一个问题取决于您访问数据的方式。

<强> 2。逐行进行

如果你可以逐行进行,只需一次读取一行文件。有60个打开的文件很容易,这不会导致任何问题。如果您按顺序处理文件,这可能是最有效的方法。内存使用率几乎为零,操作系统将无需读取文件。

操作系统和底层文件系统在顺序磁盘读写操作方面非常努力。

第3。预处理文件并使用mmap

您也可以预处理文件,使其不是CSV格式,而是二进制格式。这样,每行将在文件中精确地取17x8 = 136或17x4 = 68字节。然后,您可以使用numpy.mmap将文件映射为[N,17]形状的数组。您可以像往常一样处理数组,numpy以及操作系统将负责最佳的内存管理。

预处理是必需的,因为文本文件中的记录长度(行上的字符数)不固定。

如果您的数据访问不是连续的,那么这可能是最佳解决方案。然后mmap是最快的方法,因为它只在需要时从磁盘读取所需的块。它还会缓存数据,以便使用最佳内存量。

在幕后,这与解决方案#1密切相关,除了在需要之前没有任何内容被加载到内存中。适用于32位python的相同限制;由于内存地址不足,它无法做到这一点。

将文件转换为二进制文件相对快速简单,几乎是一行的。