如何仅使用numpy数组视图访问其边界外的对应内存位置元素
Numpy切片视图访问首元素左侧内存元素解答
问题描述
现有如下Numpy代码,创建了一个原数组的切片视图:
import numpy as np array = np.arange(10) view = array[4:8]
问是否可以仅使用view这个视图标识符,访问视图首个元素在内存中左侧的元素?
解答
结论是可以,但你无法通过视图的常规索引(比如负索引)直接访问:因为视图的常规索引范围是和切片区间绑定的,上述示例中view的合法索引范围是0~3,负索引最低支持到-4(对应索引0),超出范围的索引会直接抛出越界错误。
你可以通过以下两种方案实现访问:
- 方案1:利用Numpy视图的
base属性
所有切片生成的非拷贝视图,内置的base属性都会指向对应的原始数组对象。先计算视图首元素在原数组中的偏移量,减1即可拿到左侧元素:# 计算视图首元素在原数组中的索引偏移 offset = (view.ctypes.data - view.base.ctypes.data) // view.itemsize # 访问左侧元素,本示例中结果为3 left_element = view.base[offset - 1] - 方案2:直接操作内存地址读取
如果你不想依赖base属性,也可以通过内存偏移读取:先拿到视图首元素的内存地址,减去单个元素的字节长度就是左侧元素的地址,再按数组元素类型读取内容即可:import ctypes # 计算左侧元素的内存地址 left_addr = view.ctypes.data - view.itemsize # 按int64类型读取地址内容,32位系统请替换为ctypes.c_int32 left_element = ctypes.cast(left_addr, ctypes.POINTER(ctypes.c_int64)).contents.value
注意:上述操作都属于非常规的越界访问操作,仅当你确认目标地址属于原数组的合法内存范围时才能使用,否则会出现内存读取错误或者拿到无效垃圾值,不建议在生产代码中使用这类操作。
内容的提问来源于stack exchange,提问作者Aisec Nory
相关产品推荐
相关产品推荐

