我正在尝试了解使用 numpy
列表对 dtype
object 数组的内存和其他开销影响
与列表的列表相比。
这会随维度变化吗?例如 2D vs 3D vs N-D。
使用 numpy
数组时我能想到的一些好处是像 .shape
, .T
并且您可以使用 np.matrix
更快地将它们转换为矩阵。
还有什么吗?
另外,如果有人对我使用的对象感兴趣的话:
import gmpy2 as gm
gm.mpfr( '0' ) # <-- this is the object
编辑:
澄清一下,我对 numpy
数组类型是 object
而不是原生 numpy 类型的情况感兴趣。
编辑 2:
有关速度的相关跟进。
最佳答案
我将回答您的主要问题,而将其他问题(转置的性能等)排除在外。所以:
I'm trying to understand the memory and other overhead implications that using numpy lists would have … Just to clarify I'm interested in the case where the numpy array type is
object
not afloat
,double
orint
Python 列表是指向 Python 对象的指针数组,包装了您存储在其中的任何实际值——加上一些额外的松弛部分以允许它在运行中有效地扩展。为了便于计算,我们称其为 20%。例如,一个包含 10000 个 32 位整数的列表占用了数组的 96000 字节,加上 Python 整数对象的大约 240000 字节,再加上列表本身的少量开销,比如 80 字节。
NumPy 数组是您存储在其中的任何实际值的数组。例如,一个包含 10000 个 32 位整数的数组占用 40000 个字节,再加上数组本身的少量开销,比如 80 个字节。但是当你使用 dtype object
时,每个“实际值”只是一个指向 Python 对象的指针,就像 list
一样。
因此,这里唯一真正的区别是松弛:数组将使用 320080 字节,而列表将使用 336080 字节。差异不大,但可能很重要。
Also, does one become faster than the other in 2D vs ND or with the size along a given dimension.
是的,嵌套列表会增加得更快……但不会增加很多。
numpy 中的多维数组存储为一个巨型数组(以 C 或 Fortran 跨步顺序),因此无论形状是 (10000,)
, (100, 100)
或 (10, 10, 10, 10)
,大小相同。 (开销可能会增加几个字节以存储更多有关跨步的信息,但如果我们谈论的是 256 字节与 320K 中的 80 字节,谁在乎呢?)
另一方面,嵌套列表有更多列表,每个级别都有松弛和开销。例如,10 个列表的 10 个列表的 10 个列表的 10 个整数列表的列表有 1+10+100+1000 个包含 12 个指针的数组和 1+10+100+1000 个列表标题。
所以,数组仍然使用 320080 字节,或者可能是 320256,但列表使用 435536。
如果您想了解更多关于 list
是如何实现的……那么,这取决于您使用的实现。但是在 CPython 中,C API几乎可以保证它将存储 PyObject *
的连续数组,并且附加是分摊恒定时间的事实几乎要求它留下按比例增长的松弛。你可以在 the headers 中看到和 the source这正是它所做的。 (另外,请记住,您从该源获得的具体大小通常取决于您编译它的平台。最重要的是,因为到处都是指针,64 位平台往往在 50-100 之间大多数对象的每个对象的开销比 32 位平台多 %。)
关于python - 与 MEMORY 的 OBJECTS numpy 数组相比,列表列表的优点/缺点是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26767694/