Numpy数组内存存储机制及遍历元素重复内存地址原因咨询
问题解答
Numpy数组的内存存储方式
- Numpy数组由两部分组成:一块连续的存储原始数据的内存块,以及存储数组维度、数据类型、步长(stride)等属性的元信息头。和Python原生列表每个元素都是分散的指针不同,numpy的原始数据连续存储,数值计算时的访问效率高很多。
- 你代码中的转置操作
b = a.T不会复制原始数据,只会修改新数组元信息中的步长参数,所以才会出现a is b返回False(两个是不同的数组对象,元信息不同),但np.shares_memory(a,b)返回True(两者共享同一块原始数据内存)的结果。
遍历过程中相同id出现的原因
你观察到的不同位置整数对象内存地址相同的现象,是两个机制共同作用的结果:
- Python小整数缓存:Python默认对
[-5, 256]区间内的整数做全局缓存,这个范围内的整数全局唯一,只要数值相同,本身就是同一个对象,id自然相同。你测试用的1、2、4、5都在这个区间内,本身就有id复用的基础。 - 临时对象内存复用:当你遍历numpy数组取单个元素时,numpy会把存储的原始值转换为Python的int类型对象,这个对象是临时生成的,在打印完成后就没有其他引用了,会被Python的垃圾回收机制标记为可回收,它占用的内存地址会被释放回内存池。下一次生成新的int对象时,就可能直接复用这块空闲的内存地址,所以哪怕是不同数值的对象,只要生命周期不重叠,也会出现id相同的情况。
你代码里的for j in I属于笔误,实际运行的应该是for j in i,修正后可运行的代码如下:
import numpy as np a=np.array([[1,2],[4,5]]) b=a.T print(a is b) print(np.shares_memory(a,b)) for i in a: for j in i: print(i,j,id(j)) print('************') for i in b: for j in i: print(i,j,id(j))
内容的提问来源于stack exchange,提问作者affan skm
相关产品推荐
相关产品推荐

