如果切片不能解决内存错误,如何合并两个大的 numpy 数组?
How to merge two large numpy arrays if slicing doesn't resolve memory error?
我有两个 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
的情况下解决问题。
每次调用 np.vstack
NumPy 都必须为一个全新的数组分配 space。
所以如果我们说 1 行需要 1 个内存单元
np.vstack([container, container2])
需要 额外的 900+5000
个内存单元。此外,在分配发生之前,
Python 也需要为旧的 mergedContainer
(如果存在)保留 space
作为新的 mergedContainer
的 space。所以建造 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
重复,分配所有需要的space 一次
最开始 并写入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) 只需要 space,随机数组临时使用 space。
因此,您不必为节省内存而对代码进行太多更改。只需使用
进行设置
container = np.empty((5900, 4000))
container1 = container[:900]
container2 = container[900:]
然后使用
container1[:] = ...
而不是
container1 = ...
就地赋值。 (或者,当然,您可以直接写入 container
。)
我有两个 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
的情况下解决问题。
每次调用 np.vstack
NumPy 都必须为一个全新的数组分配 space。
所以如果我们说 1 行需要 1 个内存单元
np.vstack([container, container2])
需要 额外的 900+5000
个内存单元。此外,在分配发生之前,
Python 也需要为旧的 mergedContainer
(如果存在)保留 space
作为新的 mergedContainer
的 space。所以建造 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
重复,分配所有需要的space 一次
最开始 并写入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) 只需要 space,随机数组临时使用 space。
因此,您不必为节省内存而对代码进行太多更改。只需使用
进行设置container = np.empty((5900, 4000))
container1 = container[:900]
container2 = container[900:]
然后使用
container1[:] = ...
而不是
container1 = ...
就地赋值。 (或者,当然,您可以直接写入 container
。)