4

我有一个关于 numpys 内存视图的问题:

假设我们有两个带内存的数组:

import numpy as np
import gc
x = np.arange(4*3).reshape(4,3).astype(float)
y = (np.arange(5) - 5).astype(float)
y_ref = y

我们在框架中使用这些 ( x, y),因此我们不能只是重新定义它们,因为用户可能已经为自己链接了它们(如在 中y_ref)。现在我们想将他们的记忆合并到一个视图中。因此,单个视图p与两个数组共享内存。

我是通过以下方式做到的,但不知道这是否会导致内存泄漏:

p = np.empty(x.size+y.size, dtype=float) # create new memory block with right size
c = 0 # current point in memory

# x
p[c:c+x.size].flat = x.flat # set the memory for combined array p
x.data = p[c:c+x.size].data # now set the buffer of x to be the right length buffer of p

c += x.size

# y
p[c:c+y.size].flat = y.flat # set the memory for combined array p
y.data = p[c:c+y.size].data # and set the buffer of x to be the right length buffer of p

因此,我们现在可以对单个视图p或其中一个数组进行操作,而无需重新定义对它们的每个引用

x[3] = 10
print p[3*3:4*3]
# [ 10.  10.  10.]

甚至y_ref得到了更新:

print y[0] # -5
y_ref[0] = 100
print p[x.size] # 100

这是将数组的内存设置为另一个数组的视图的正确方法吗?

有没有一种明显的方法来统一我公然失踪的数组内存?

我不确定旧数据缓冲区会发生什么xy因为它们现在超出了范围。他们会被解除分配吗?

更新感谢@Jaime:

p.size在我申请的数据集(微生物学)上可以变得非常大(数十亿)。此外,此主题用于具有潜在深层结构的框架中,因此更新所有本地版本可能会变得昂贵。所有参数的更新都需要在优化循环中完成,因此将所有内容都保存在内存中至关重要。

实际上,您的方法是我最初的方法,因为使用 python 层次结构遍历来更新所有本地副本效率低下。

4

1 回答 1

3

根据源代码,旧的数据缓冲区将被释放。

https://github.com/numpy/numpy/blob/6c6ddaf62e0556919a57d510e13ccb2e6cd6e043/numpy/core/src/multiarray/getset.c#L329

但是如果旧缓冲区被其他数组引用,则会导致问题:

import numpy as np

a = np.zeros(10)
b = np.zeros(10)
c = a[:]
a.data = b
print c
于 2014-05-14T11:22:08.657 回答