Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如果切片不成功,如何合并两个大的numpy数组';无法解决内存错误?_Python_Numpy_Data Analysis - Fatal编程技术网

Python 如果切片不成功,如何合并两个大的numpy数组';无法解决内存错误?

Python 如果切片不成功,如何合并两个大的numpy数组';无法解决内存错误?,python,numpy,data-analysis,Python,Numpy,Data Analysis,我有两个numpy数组container1和container2,其中container1.shape=(9004000)和container2.shape=(50004000)。使用vstack合并它们会产生MemoryError。在搜索了这里发布的旧问题后,我尝试使用切片将它们合并,如下所示: mergedContainer = numpy.vstack((container1, container2[:1000])) mergedContainer = numpy.vstack((merg

我有两个numpy数组
container1
container2
,其中
container1.shape=(9004000)
container2.shape=(50004000)
。使用
vstack
合并它们会产生
MemoryError
。在搜索了这里发布的旧问题后,我尝试使用
切片将它们合并,如下所示:

mergedContainer = numpy.vstack((container1, container2[:1000]))
mergedContainer = numpy.vstack((mergedContainer, container[1000:2500]))
mergedContainer = numpy.vstack((mergedContainer, container[2500:3000]))
container1 = container[:900]   
container2 = container[900:]   
但在此之后,即使我这样做:

mergedContainer = numpy.vstack((mergedContainer, container[3000:3100]))
它会导致
内存错误


我正在使用
Python 3.4.3(32位)
,每次调用
np时,我希望不转换为
64位
。vstack
NumPy必须为一个全新的数组分配空间。 所以如果我们说一行需要一个单位的内存

np.vstack([container, container2])
需要额外的
900+5000
内存单位。而且在任务发生之前,, Python还需要为旧的
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
重复地,分配一次所需的所有空间 开始时写下容器1的内容
将容器2
放入其中。换句话说,避免分配两个不同的阵列
container1
container2
如果您知道最终要合并它们

container = np.empty((5900, 4000))
请注意,和视图需要 基本上没有额外的内存。因此您可以定义
container1
容器2
如下:

mergedContainer = numpy.vstack((container1, container2[:1000]))
mergedContainer = numpy.vstack((mergedContainer, container[1000:2500]))
mergedContainer = numpy.vstack((mergedContainer, container[2500:3000]))
container1 = container[:900]   
container2 = container[900:]   
然后在适当的位置指定值。这将修改容器

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 = ...

在适当位置指定值。(当然,您也可以在每次调用
np时直接写入
container

。 所以如果我们说一行需要一个单位的内存

np.vstack([container, container2])
需要额外的
900+5000
内存单位。而且在任务发生之前,, Python还需要为旧的
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
重复地,分配一次所需的所有空间 开始时写下容器1的内容
将容器2
放入其中。换句话说,避免分配两个不同的阵列
container1
container2
如果您知道最终要合并它们

container = np.empty((5900, 4000))
请注意,和视图需要 基本上没有额外的内存。因此您可以定义
container1
容器2
如下:

mergedContainer = numpy.vstack((container1, container2[:1000]))
mergedContainer = numpy.vstack((mergedContainer, container[1000:2500]))
mergedContainer = numpy.vstack((mergedContainer, container[2500:3000]))
container1 = container[:900]   
container2 = container[900:]   
然后在适当的位置指定值。这将修改容器

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 = ...

在适当位置指定值。(或者,当然,您可以直接写入
容器

您有多少RAM以及当前使用了多少RAM?合并后的阵列应该只需要大约95MB(假设您使用的是int32数据类型)。(您可以使用
np.who()
查看内存中的阵列。)@ajcr我的电脑中有4 GB的RAM。您有多少RAM?您当前使用了多少RAM?合并后的阵列应该只需要大约95MB(假设您使用的是int32数据类型)。(您可以使用
np.who()
查看内存中的阵列。)@ajcr我的电脑中有4 GB RAM。我刚刚发现,如果我从容器中删除一列,它仍然显示在container1或container2中。这不是针对视图吗?视图包含对共享底层数组的引用——例如,在修改
容器之前,
容器1.base is container
应该是
True
。如果将
container
重新定义为
container
的一部分(从而“删除”列),它将成为原始基础数组的视图,并且
container.base
可能等于原始
container
。因此,
container
container1
container2
仍保留对原始
容器的引用。因此,将
container
重新绑定到新值不会影响
container1
container2
。您的就地分配解决方案如何比单个
vstack
调用更好?无论哪种方式,它都会为新的大数组分配一次空间。@sudo:
container1
需要,比如说,
A
字节的空间<代码>容器2
需要
B
字节
vstack([container1,container2])
将需要
A+B
字节。所以您需要
2*(A+B)
字节的总空间。如果你们都