【发布时间】:2022-01-14 10:24:12
【问题描述】:
我现在已经更详细地处理了 numpy 数组。您总是读到 numpy ndarray 使用较少的内存,但如果您查看总内存消耗,ndarray 比列表大得多。
在列表中,我们有大小为 28 字节的 int 对象,但在 numpy 数组中,我们有大小为 32 字节的 numpy.int64 对象。
所以我只是不明白为什么他们说 numpy 对象使用更少的内存,因为 numpy.int64 对象比 int 对象大四个字节。
import numpy as np
from sys import getsizeof
def is_iterable(p_object):
try:
iter(p_object)
except TypeError:
return False
return True
def get_total_size(element, size):
if not is_iterable(element):
return size + getsizeof(element)
size = size + getsizeof(element)
for new_element in element:
size = get_total_size(new_element, size)
return size
if __name__ == "__main__":
x_list = list(range(100))
x_array = np.array(x_list)
print("x_list:")
print("A list with object references consumes in memory " + str(getsizeof(x_list)) + " Byte(s)")
print("A list of object references and all objects consumed in memory " + str(get_total_size(x_list, 0)) + " Byte(s)")
print("")
print("Numpy-Array:")
print("A ndarray object references consumes in memory " + str(getsizeof(x_array)) + " Byte(s)")
print("A ndarray of object references and all objects consumed in memory " + str(get_total_size(x_array, 0)) + " Byte(s)")
print("")
print("objecttype", type(x_array[1]), "size in bytes", getsizeof(x_array[1]), )
print("objecttype", type(x_list[1]), "size in bytes", getsizeof(x_list[1]), )
输出:
x_list:
A list with object references consumes in memory 1016 Byte(s)
A list of object references and all objects consumed in memory 3812 Byte(s)
Numpy-Array:
A ndarray object references consumes in memory 896 Byte(s)
A ndarray of object references and all objects consumed in memory 4096 Byte(s)
objecttype <class 'numpy.int64'> size in bytes 32
objecttype <class 'int'> size in bytes 28
【问题讨论】:
-
这能回答你的问题吗? Python3 numpy array size compare to list
-
您的数组不是对象 dtype,因此不需要添加“引用”。您的列表处理没问题(比大多数都好),但您可能还想检查浮点数或更大的整数。但是内存使用并不是 numpy 的主要优势。计算速度是(如果做得对的话)。
-
Julien 的参考资料可能是您问题的答案,但无论如何您都可以使用
x_array = np.array(x_list, dtype=np.int32)。 -
您没有正确获取对象的内存消耗。重要的是,
objecttype <class 'numpy.int64'> size in bytes 32无关紧要。numpy.ndarray对象本质上是原始数组的面向对象的包装器。要获取底层缓冲区的大小,您只需要x_array.nbytes