【问题标题】:numpy memory usage when assigning new values分配新值时的 numpy 内存使用情况
【发布时间】:2019-01-30 03:40:49
【问题描述】:

我有一个批量生成数据的数据生成类。简化如下:

import numpy as np
import os
import psutil


def memory_check():
    pid = os.getpid()
    py_mem = psutil.Process(pid)
    memory_use = py_mem.memory_info()[0] / 2. ** 30
    return {"python_usage": memory_use}


class DataBatcher:
    def __init__(self, X, batch_size):
        self.X = X
        self.start = 0
        self.batch_size = batch_size
        self.row_dim, col_dim = X.shape
        self.batch = np.zeros((batch_size, col_dim))

    def gen_batch(self):
        end_index = self.start + self.batch_size
        if end_index < self.row_dim:
            indices = range(self.start, end_index)
            print("before assign batch \n", memory_check())
            self.batch[:] = self.X.take(indices, axis=0, mode='wrap')
            print("after assign batch \n", memory_check())
            self.start = end_index
            return self.batch


if __name__ == "__main__":
    X = np.random.sample((1000000, 50))
    for i in range(100):
        data_batcher = DataBatcher(X, 5000)
        x = data_batcher.gen_batch()

除了 self.X 是在 DataBatcher 类中的另一个方法中生成的并且它会定期更新之外,实际代码与上面的代码非常接近。我注意到,当 self.X 没有发生任何更改时,Python 的内存使用量在每一轮都在稳步增加 self.batch[:] = self.X.take(indices, axis=0, mode='wrap')。我认为这不应该是因为我为self.batch 预先分配了内存?

【问题讨论】:

  • take 确实创建了一个新的临时数组对象(具有自己的数据缓冲区)。是的,它确实被分配给self.batch。但是我们不知道numpy 和/或 Python 对临时数组/缓冲区做了什么。 numpy 似乎做了一些自己的内存管理,这些管理独立于(或高于)Python 自己的垃圾收集。

标签: python numpy memory


【解决方案1】:

正如Why does numpy.zeros takes up little space 中所回答的那样,这种令人惊讶的行为可能是一些操作系统级别的优化:np.zeros 实际上并不占用内存,因为您使用self.batch[:] = self.X.take(indices, axis=0, mode='wrap') 有效地在其上写入

【讨论】:

  • 但是第一轮过后内存应该不会一直上升吧?
  • 每次从默认值更改数组中的位置时,它都会增加
猜你喜欢
  • 2014-07-31
  • 2020-11-27
  • 2011-06-24
  • 1970-01-01
  • 2012-07-31
  • 2015-12-02
  • 2012-12-05
  • 1970-01-01
相关资源
最近更新 更多