Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.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_Arrays_Numpy_Memory - Fatal编程技术网

Python 用最少的内存连接Numpy数组

Python 用最少的内存连接Numpy数组,python,arrays,numpy,memory,Python,Arrays,Numpy,Memory,不是我有50GB的数据集保存为h5py,这是一个字典里面。字典包含从0到n的键,值为numpy ndarray(三维),形状相同。例如: 字典[0]=np.array([[…],[…]] 我想对所有这些np数组进行压缩,代码如下 sample = np.concatenate(list(dictionary.values)) 此操作浪费100GB内存!如果我使用 del dictionary 它将减少到50GB内存。但我希望在加载数据期间将内存使用控制为50GB。我试过的另一种方法是这样

不是我有50GB的数据集保存为h5py,这是一个字典里面。字典包含从0到n的键,值为numpy ndarray(三维),形状相同。例如:

字典[0]=np.array([[…],[…]]

我想对所有这些np数组进行压缩,代码如下

sample = np.concatenate(list(dictionary.values))
此操作浪费100GB内存!如果我使用

del dictionary
它将减少到50GB内存。但我希望在加载数据期间将内存使用控制为50GB。我试过的另一种方法是这样

    sample = np.concatenate(sample,dictionary[key])
sample = np.empty(shape)
with h5py.File(...) as dictionary:
    for key in dictionary.keys():
        sample[key] = dictionary[key]
它仍在使用100GB内存。我认为在上述所有情况下,右侧将创建一个新的内存块进行保存,然后分配给左侧,这将在计算期间使内存加倍。因此,第三种方法我是这样尝试的

    sample = np.concatenate(sample,dictionary[key])
sample = np.empty(shape)
with h5py.File(...) as dictionary:
    for key in dictionary.keys():
        sample[key] = dictionary[key]
我认为这个代码有一个优势。将值dictionary[key]分配给样本的某一行,那么dictionary[key]的内存将被清除。但是,我测试了它,发现内存使用量也是100GB。为什么?


有没有什么好方法将内存使用限制为50GB

您的问题是,内存中需要有相同数据的两个副本。 如果按照
test1
中的方式构建数组,那么一次所需的内存将少得多,但代价是丢失字典

import numpy as np
import time    

def test1(n):
    a = {x:(x, x, x) for x in range(n)} # Build sample data
    b = np.array([a.pop(i) for i in range(n)]).reshape(-1)
    return b

def test2(n):
    a = {x:(x, x, x) for x in range(n)} # Build sample data
    b = np.concatenate(list(a.values()))
    return b

x1 = test1(1000000)
del x1

time.sleep(1)

x2 = test2(1000000)
结果:


第一次查看是针对test1的,它没有完全就位,但它大大减少了内存使用。

字典[key]
是文件中的数据集
dictionary[key][…]
将是一个numpy数组,数据集已下载

我想

sample[key] = dictionary[key]
被评估为

sample[key,...] = dictionary[key][...]
下载数据集,然后将其复制到
样本
数组的一个片段中。下载的阵列应该可以免费回收。但numpy/python是否做到这一点则是另一回事。我没有打破记忆极限的习惯

您不想进行增量连接-这太慢了。列表上的单个连接应该更快。我不知道为什么会这样

list(dictionary.values)
包含。它是对数据集的引用,还是下载的数组?无论如何,
concatenate(…)
在该列表中必须使用下载的数组


有一件事让我感到困惑-您如何使用相同的
索引
示例
的第一维度和
字典中的数据集
h5py
键应该是字符串,而不是整数


一些测试

请注意,我使用的是字符串数据集名称:

In [21]: d = f.create_dataset('0',data=np.zeros((2,3)))
In [22]: d = f.create_dataset('1',data=np.zeros((2,3)))
In [23]: d = f.create_dataset('2',data=np.ones((2,3)))
In [24]: d = f.create_dataset('3',data=np.arange(6.).reshape(2,3))
您的
np.concatenate(列表(dictionary.values))
代码缺失
()

e、 g:

让我们看看使用迭代方法时会发生什么:

创建一个数组,该数组可以为每个“行”获取一个数据集:

In [34]: samples = np.zeros((4,2,3),float)
In [35]: for i,d in enumerate(f.values()):
    ...:     v = d[...]
    ...:     print(v.__array_interface__['data']) # databuffer location
    ...:     samples[i,...] = v
    ...:     
(27845184, False)
(27815504, False)
(27845184, False)
(27815504, False)
In [36]: samples
Out[36]: 
array([[[0., 0., 0.],
        [0., 0., 0.]],

       [[0., 0., 0.],
        [0., 0., 0.]],

       [[1., 1., 1.],
        [1., 1., 1.]],

       [[0., 1., 2.],
        [3., 4., 5.]]])
在这个小示例中,它循环使用其他每个databuffer块。第二次迭代释放了第一次迭代中使用的数据缓冲区,然后可以在第三次迭代中重用,以此类推


这些是交互式
ipython
会话中的小数组。我不知道这些观察结果是否适用于大型情况。

如何绘制RAM图片?变量a不是必需的,我连接到h5py,并从中获取数据,如何在不将其放入字典的情况下弹出它?它不应该是“np.array([a.pop(0)表示范围(n)中的I)]。重塑(-1)”(0,不是I)?此外,它对我也不起作用,当使用它而不是“a=np.concatenate(mylist,axis=0)”列表(dictionary.values)引用到数据集时,仍然会出现内存错误,concatenate将添加新的RAM。我自己的程序中的键已转换为int类型。迭代案例是一项很好的工作。可能与:
In [29]: [np.array(a) for a in f.values()]
Out[29]: 
[array([[0., 0., 0.],
        [0., 0., 0.]]), array([[0., 0., 0.],
        [0., 0., 0.]]), array([[1., 1., 1.],
        [1., 1., 1.]]), array([[0., 1., 2.],
        [3., 4., 5.]])]
In [30]: [a[...] for a in f.values()]
    ....
In [34]: samples = np.zeros((4,2,3),float)
In [35]: for i,d in enumerate(f.values()):
    ...:     v = d[...]
    ...:     print(v.__array_interface__['data']) # databuffer location
    ...:     samples[i,...] = v
    ...:     
(27845184, False)
(27815504, False)
(27845184, False)
(27815504, False)
In [36]: samples
Out[36]: 
array([[[0., 0., 0.],
        [0., 0., 0.]],

       [[0., 0., 0.],
        [0., 0., 0.]],

       [[1., 1., 1.],
        [1., 1., 1.]],

       [[0., 1., 2.],
        [3., 4., 5.]]])