所以最近我一直在做一个优化项目,我想使用numpy数组而不是python内置列表。它将是一个在两个轴上都具有固定长度的二维阵列。我还想最大限度地使用现金,使代码尽可能快。但是,当使用id(var)函数时,会出现意外结果:
代码:
a = numpy.ascontiguousarray([1,2,3,4,5,6,7,8,9], dtype=numpy.int32)
for var in a:
print(hex(id(var)))
返回:
x1aaba10d8f0
0x1aaba1f33d0
0x1aaba10d8f0
0x1aaba1f33d0
0x1aaba10d8f0
0x1aaba1f33d0
0x1aaba10d8f0
0x1aaba1f33d0
0x1aaba10d8f0
这对我来说是非常奇怪的,这意味着两个变量位于同一个内存块中(这是一件事吗?)。不管怎样,是我没有正确地理解它吗
作为一个附带问题,是否可以用成本较低的方法完成构建二维阵列的原始任务?Numpy阵列附带了许多我不需要的函数。我只需要两样东西:
提前感谢您的帮助:-)
id(var)
并不像您想象的那样工作。实际上,id(var)
返回指定对象var
的唯一ID,但var
不是a
的单元格var
是一个Python对象,它引用了a
的单元格。请注意a
不包含这样的对象,因为它效率太低(并且数据不会按要求连续)。看到重复ID的原因是以前的var
对象已被回收您真正想要的阵列类型不清楚,目的也不清楚。但谈到连续(或连续)和缓存,表明您不清楚Python是如何工作的
首先,Python一直都是面向对象的。整数、字符串、列表都是某个类的对象,具有相关的方法和属性。对于内置类,我们对存储几乎没有发言权
让我们列出一个小清单:
列表有一个数据缓冲区,用于存储指向内存中其他位置的对象的引用(如果愿意,可以使用指针)。
id
可能会给出一些关于where的概念,它不应该被理解为c
语言意义上的“指针”对于此列表:
1,2,3的id值很小,因为Python在开始时初始化了小整数(最多256个)。因此,所有使用都将具有唯一的id
在列表创建中
1000
似乎是唯一的,但在该上下文之外并非如此看起来字符串也被缓存了——但这只是解释器的选择,我们不应该指望它
反向列表是一个新列表,具有自己的指针数组。但参考文献相同:
像
[::-1]
这样的索引操作应该只取决于列表中的项目数。它不取决于值实际指向的位置。其他副本也一样。即使是附加到数组中,也是相对独立于时间的(它在数据缓冲区中保持增长空间)。实际处理列表中的对象可能取决于它们存储在内存中的位置,但我们对此没有什么可说的“2d”列表实际上是包含列表元素的列表;嵌套列表。子列表存储在内存中的其他位置,就像字符串和数字一样。从这个意义上说,嵌套列表是不连续的
那么阵列呢
x
是一个ndarray
对象,具有shape
、strides
和dtype
等属性。和一个数据缓冲区。在本例中,是96字节长的c
数组,在“57148880. We can't use that number, but I find it useful when comparing this
数组接口dict across arrays. A
视图`尤其具有相同或相关的值数组数据缓冲区具有实际值,而不是引用。这里使用
int
dtype,每个8字节被解释为一个“int64”值你的
id
迭代有效地要求一个列表[x[i] for i in range(n)]
。数组的元素必须是“未绑定的”,并且是一个新对象,类型为np.int64
。虽然不是数组,但它确实有许多与1元素数组相同的属性该
data
值与x
值无关只要在现有数组上使用
numpy
方法,速度就很好,通常比同等的列表方法快10倍。但是如果从列表开始,则创建数组需要时间。而且像列表一样处理数组的速度很慢而
x
的反面呢这是一个新的数组,但是有一个不同的
strides
(-8,),并且data
指向缓冲区的末尾880+96-8
相关问题 更多 >
编程相关推荐