Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/359.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 - Fatal编程技术网

Python 将列表转换为numpy数组会产生比预期大得多的内存

Python 将列表转换为numpy数组会产生比预期大得多的内存,python,arrays,numpy,Python,Arrays,Numpy,我有一个2940个元素的列表-每个元素是一个(602094)numpy数组 print('DataX:') print('len:') print(len(dataX)) print('shape:') for i in range(5): print(dataX[i].shape) print('dtype:') print(dataX[0].dtype) print('size',sys.getsizeof(dataX)/1000000) 结果: DataX: len: 2940

我有一个2940个元素的列表-每个元素是一个(602094)numpy数组

print('DataX:')
print('len:')
print(len(dataX))
print('shape:')
for i in range(5):
    print(dataX[i].shape)
print('dtype:')
print(dataX[0].dtype)

print('size',sys.getsizeof(dataX)/1000000)
结果:

DataX:
len:
2940
shape:
(60, 2094)
(60, 2094)
(60, 2094)
(60, 2094)
(60, 2094)
dtype:
float64
size 0.023728
但是,如果我尝试将其转换为一个numpy数组(其结果应该是(2940,602094)的形状),那么数组的大小要大得多

#convert list to array

X = np.array(dataX)
print('X:')
print('shape', X.shape)
print('size',sys.getsizeof(X)/1000000)
输出:

DataX:
shape (2940, 60, 2094)
size 2955.052928
为什么会这样

如果我使用更大的数据集进行尝试,最终会出现“内存”错误。

来自:

只有直接归因于该对象的内存消耗才会被忽略 已计算,而不是它所指对象的内存消耗

sys.getsizeof
返回列表对象本身的内存消耗,不包括列表包含的对象。单个数组:

In [3]: arr = np.zeros(dtype=np.float64, shape=(60, 2094))

In [4]: arr.size
Out[4]: 125640

In [5]: arr.nbytes
Out[5]: 1005120 
包装基元数组的python对象添加了大约100个字节

注意,作为一个对象总是有开销,注意:

In [6]: sys.getsizeof(arr)
Out[6]: 1005232
那么,实际内存消耗量约为:

In [7]: arr.nbytes*1e-9
Out[7]: 0.00100512 # one megabyte
如果我们有2940个,那么这些物体就是:

In [8]: arr.nbytes*2940*1e-9
Out[8]: 2.9550528000000003 # almost 3 gigabytes
如果我真的把这些都列在一个列表中:

In [13]: alist = []

In [14]: alist.append(arr)

In [15]: for _ in range(2940 - 1):
    ...:     alist.append(arr.copy())
    ...:
list对象本身基本上由py_对象指针数组支持。在我的机器上(64位),指针将是一个机器字,即64位或8字节。因此:

In [19]: sys.getsizeof(alist)
Out[19]: 23728

In [20]: 8*len(alist) # 8 bytes per pointer
Out[20]: 23520
因此,
sys.getsizeof
只考虑了指针数组,加上对象开销,但这还不足以考虑被指向的数组对象消耗的3g字节

你瞧:

In [21]: arr = np.array(alist)

In [22]: arr.shape
Out[22]: (2940, 60, 2094)

In [23]: arr.size
Out[23]: 369381600

In [24]: arr.nbytes
Out[24]: 2955052800

In [25]: arr.nbytes* 1e-9
Out[25]: 2.9550528000000003

你读过关于sys.getsizeof的文档了吗?嗨,你是说这一部分吗“但这不一定适用于第三方扩展,因为它是特定于实现的。”我认为在我的情况下不适用,因为当我增加数据大小时,
X
会出现“内存”错误,但似乎没有得到“内存”数组列表出现错误。我还使用任务管理器检查了内存大小,结果似乎是正确的。
sys.getsizeof
只提供列表的大小,不包括列表中的对象。这是造成差异的原因。谢谢。我只想明天运行一些测试,以确保这一点,因为我遇到了some关于您刚才列出的内容的冲突行为。@Moondra需要了解的另一件事是,当您执行
arr=np.array(alist)
时,由于数据是复制的而不是共享的,所以它将需要双精度