DataFrame转numpy数组后值同步变化但id()显示内存地址不同的疑问
为什么DataFrame列转numpy数组后共享值但元素id不同?
核心问题:你检查的不是底层共享内存的地址
当通过df['column1'].to_numpy()生成数组时,只要列的数据类型是numpy兼容的原生类型(比如示例中的int64),返回的数组会直接引用DataFrame列的底层内存缓冲区——这才是修改数组后DataFrame同步变化的根本原因。但你用id(i)查看的是遍历过程中生成的Python整数对象的地址,和底层内存块完全无关。
1. 遍历操作会生成临时Python对象
- 遍历pandas Series(
df['column1'])时,每一个元素都会被转换为Python的int对象,这些对象要么是临时创建的,要么来自Python的小整数缓存池,它们的id是这些Python对象在堆内存中的地址,和DataFrame底层的numpy存储无关。 - 遍历numpy数组时,取出的元素同样会被“装箱”成Python
int对象,这些对象的id也不是底层数组中原始数值的存储地址。
2. 小整数缓存导致重复id
Python会自动缓存**-5到256之间的整数**,当取出这个范围内的整数时,会复用同一个Python对象。示例中col1_arr[0](100)和col1_arr[2](33)都属于这个范围,所以会共享同一个对象,出现id相同的情况。
验证内存共享的正确方式
要确认DataFrame列和numpy数组是否共享内存,应该检查它们底层数组的内存地址,而非单个元素的Python对象id:
# 查看DataFrame列底层数组的内存起始地址 print(hex(df['column1'].values.base.__array_interface__['data'][0])) # 查看to_numpy()生成数组的内存起始地址 print(hex(col1_arr.__array_interface__['data'][0]))
运行后会发现两个地址完全一致,证明二者共享同一块底层内存缓冲区。
总结
- 修改数组后DataFrame同步更新,是因为二者共享底层numpy内存块,而非单个Python元素对象。
id(i)返回的是遍历生成的Python整数对象地址,和底层存储无直接关联。- 数组中元素id重复是Python小整数缓存机制的正常表现。
内容的提问来源于stack exchange,提问作者Kaiser
相关产品推荐
相关产品推荐

