【问题标题】:Incrementally building a numpy array and measuring memory usage增量构建 numpy 数组并测量内存使用情况
【发布时间】:2010-12-04 14:18:24
【问题描述】:

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

  • 由于加载开始时行数未知,如何 一个非常大的 numpy 数组是最有效地逐行构建的吗?

简单地将行添加到数组中在内存方面效率低下,因为两个大数组会暂时共存。如果您使用numpy.append,似乎也会出现同样的问题。 stack 函数很有前途,但理想情况下我希望将数组扩大到适当的位置。

这就引出了第二个问题:

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

为了研究上述问题,我使用了常用的内存分析工具——heapy 和 pymler——但我只获得了外部数组对象的大小(80 字节),而不是它们包含的数据。除了粗略测量 Python 进程正在使用多少内存之外,随着数组的增长,我如何才能获得数组的“完整”大小?

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

【问题讨论】:

    标签: python numpy memory-management


    【解决方案1】:

    除了创建一个最大可能大小的空数组 (numpy.empty) 并在最后使用该视图之外,没有其他方法可以确保您可以适当地扩展数组。您不能从小处着手,因为无法保证您可以在不破坏其他一些数据的情况下扩展地图的任何内存。 (而且所有这些都远低于 python 允许您从解释器内部获取的级别。)

    您最好的选择可能是numpy.fromiter。看源码,随着项目数量的增加,数组每次扩展50%多一点。如果您可以轻松获得行数(例如通过计算行数),您甚至可以将其传递给计数。

    【讨论】:

      【解决方案2】:

      您是否尝试过使用 memmap 文件?您可以遍历输入文件(如果可能,以块的形式)并转换传入数据并将它们作为行插入到内存映射的 numpy 数组中。不利的一面是,如果主内存不足并且需要从交换中进行分页,则会产生更多的磁盘 i/o。

      见:http://docs.scipy.org/doc/numpy/reference/generated/numpy.memmap.html

      另一种选择是 PyTables。您需要构建一些特殊的类似 sql 的表,但它相当简单。事实上,它为您的数据提供了透明的磁盘持久性(自动序列化)和分层组织。它还限制了主内存的使用量。

      参见:www.pytables.org/moin/HowToUse

      祝你好运!

      【讨论】:

        【解决方案3】:

        一个可能的选项是先对文件进行一次遍历以计算行数,而不加载它们。

        另一种选择是每次将您的表格大小加倍,这有两个好处:

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

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

        【讨论】:

        • 谢谢大家。考虑到文件的大小,我不愿意为了计算行数而进行初始传递,但这似乎是解决内存问题的最简单和最有效的方法。
        • 我最近有一位同事问了一个类似的问题,我想出了另一种可能使您免于初次通过的可能性。如果您知道文件中某个“元素”的大致大小,则可以将其划分为文件大小。添加一些填充以确保安全,然后您可以写入整个内存。要隐藏额外的未初始化的,您可以使用仅包含数据的元素的视图。你需要确保你不会过去。它并不完美,但如果您的文件读取速度很慢,并且您的数据布局一致,它可能会起作用。
        【解决方案4】:

        问题本质上是文本文件。当您的输入数据存储在更高级的来源中时,可以避免此类问题。以h5py project 为例。首先将数据转换为 HDF5 文件,然后对 HDF5 文件运行分析脚本是值得的。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-07-31
          • 2014-05-11
          • 2017-01-03
          • 2011-02-27
          相关资源
          最近更新 更多