我有两个numpy数组container1
和container2
container1.shape = (900,4000)
和container2.shape = (5000,4000)
。使用vstack
合并它们会产生MemoryError
。在搜索此处发布的旧问题后,我尝试使用slicing
合并它们,如下所示:
mergedContainer = numpy.vstack((container1, container2[:1000]))
mergedContainer = numpy.vstack((mergedContainer, container[1000:2500]))
mergedContainer = numpy.vstack((mergedContainer, container[2500:3000]))
但在此之后即使我这样做了:
mergedContainer = numpy.vstack((mergedContainer, container[3000:3100]))
导致MemoryError
。
我正在使用Python 3.4.3 (32-Bit)
,希望在不转移到64-Bit
的情况下解决。
答案 0 :(得分:3)
每次拨打np.vstack
时,NumPy必须为全新阵列分配空间。
因此,如果我们说1行需要1个单位的内存
np.vstack([container, container2])
需要额外的 900+5000
内存单元。而且,在转让之前,
Python需要为旧mergedContainer
(如果存在)保留空间
作为新mergedContainer
的空间。所以建立mergedContainer
迭代地使用切片实际上需要比尝试构建它更多的内存
只需拨打np.vstack
。
迭代构建它:
| total | mergedContainer | container1 | container2 | temp | |
|-------+-----------------+------------+------------+------+----------------------------------------------------------------------|
| 7800 | 1900 | 900 | 5000 | 0 | mergedContainer = np.vstack((container1, container2[:1000])) |
| 11200 | 3400 | 900 | 5000 | 1900 | mergedContainer = np.vstack((mergedContainer, container[1000:2500])) |
| 13200 | 3900 | 900 | 5000 | 3400 | mergedContainer = np.vstack((mergedContainer, container[2500:3000])) |
从一次调用构建它到np.vstack:
| total | mergedContainer | container1 | container2 | temp | |
|-------+-----------------+------------+------------+------+-------------------------------------------------------|
| 11800 | 5900 | 900 | 5000 | 0 | mergedContainer = np.vstack((container1, container2)) |
然而,我们可以做得更好。而不是致电np.vstack
反复,分配一次所需的所有空间
一开始并写下container1
和。{的内容
container2
进入它。换句话说,避免分配两个不同的数组
container1
和container2
,如果您最终知道要合并它们。
container = np.empty((5900, 4000))
请注意basic slices such as container[:900]
always return views和视图需要
基本上没有额外的记忆所以你可以定义container1
和
container2
喜欢这样:
container1 = container[:900]
container2 = container[900:]
然后分配值到位。这会修改container
:
container1[:] = ...
container2[:] = ...
因此你的记忆要求将保持在5900左右。
例如,
import numpy as np
np.random.seed(2015)
container = np.empty((5, 4), dtype='int')
container1 = container[:2]
container2 = container[2:]
container1[:] = np.random.randint(10, size=(2,4))
container2[:] = np.random.randint(1000, size=(3,4))
print(container)
产量
[[ 2 2 9 6]
[ 8 5 7 8]
[112 70 487 124]
[859 8 275 936]
[317 134 393 909]]
虽然只需要一个形状数组(5,4)的空间,以及随机数组的临时空间。
因此,您不必在代码中进行大量更改以节省内存。只需使用
进行设置即可container = np.empty((5900, 4000))
container1 = container[:900]
container2 = container[900:]
然后使用
container1[:] = ...
而不是
container1 = ...
分配值就地。 (或者,当然,您可以直接写入container
。)