逐步构建NumPy数组并测量内存使用情况

11

我有一系列的大型文本文件(高达1GB),这些文件是实验输出,需要在Python中进行分析。最好将它们加载到2D numpy数组中,这引发了第一个问题:

  • 由于在加载开始时行数不确定,如何最有效地逐行构建非常大的numpy数组?

简单地将行添加到数组中,在内存方面效率低下,因为两个大数组会短暂共存。如果使用numpy.append也会出现同样的问题。虽然stack函数很有前景,但理想情况下我希望能够原地增加数组。

这引出了第二个问题:

  • 观察 Python 程序严重使用 numpy 数组时的内存使用情况的最佳方法是什么?

为了研究上述问题,我已经使用了通常的内存分析工具 - heapy 和 pympler - 但只得到了外部数组对象的大小(80字节),而没有获取其中包含的数据。除了粗略测量Python进程使用的内存量之外,我如何获得随着数组增长其“完整”大小的信息?

本地详细信息:OSX 10.6,Python 2.6,但欢迎提供通用的解决方案。

4个回答

7

没有办法确保你可以在原地扩展数组,除非创建一个最大可能大小的空数组(numpy.empty),然后在最后使用该视图。你不能从小开始,因为没有保证您可以扩展映射的任何内存而不破坏其他数据。(所有这些都比Python允许您从解释器内部获得的要低级得多。)

你最好的选择可能是numpy.fromiter。查看源代码,随着项目数量的增加,每次扩展数组的大小都会增加一半左右。如果您可以轻松获取行数(例如通过计算行数),甚至可以传递计数。


2
你尝试过使用memmap文件吗?你可以迭代遍历你的输入文件(如果可能的话分块),将传入数据转换为行并插入到一个内存映射的numpy数组中。缺点是如果主存储器不足,需要进行更多的磁盘I/O,并从交换空间进行页面替换。
参见:http://docs.scipy.org/doc/numpy/reference/generated/numpy.memmap.html 另一种选择是PyTables。你需要构建一些特殊的类似于SQL的表,但它非常简单。实际上,它提供了自动序列化的透明磁盘持久性以及数据的分层组织。它还限制了使用的主存储器的数量。
参见:www.pytables.org/moin/HowToUse 祝你好运!

1

一种可能的选项是首先对文件进行单通道处理,以计算行数,而不必读取它们。

另一个选择是每次将表格大小翻倍,这有两个优点:

  1. 你只需重新分配内存 log(n) 次,其中 n 是行数。
  2. 你所需的最大内存大小仅比最大表格大小多 50%。

如果你采用动态路线,可以通过测量第一行的字节数来估算行数,然后通过计算(文件中的字节数 / 第一行中的字节数)来猜测。从这个大小的表格开始。


谢谢大家。考虑到文件的大小,我不太愿意进行初始遍历以计算行数,但这似乎是解决内存问题最简单和最有效的方法。 - user185536
1
我最近有个同事问了一个类似的问题,我想到了另一种可能性,可以避免初始传递。如果您知道文件中“元素”的大致大小,则可以将其分成文件大小。添加一些填充以确保安全,并可以写入整个内存。为了隐藏额外的未初始化内容,您可以使用仅包含数据的元素视图。您需要确保不超过范围。这并非完美,但如果您的文件读取速度很慢,并且您的数据布局一致,它可能有效。 - AFoglia

0
问题实际上在于文本文件。当您的输入数据以更高级的形式存储时,这些问题可以避免。例如,请看h5py项目。值得花费一些精力将数据首先转换为HDF5文件,然后在HDF5文件上运行分析脚本。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接