url地址如何获取_如何获取numpy数组的真实地址?如何与ctypes数组共享内存?

1、如何获取numpy数组元素的真实地址?

在Python编程中,numpy是一个很好用的扩展程序库,将其与SciPy库和 Matplotlib绘图库一起使用,可构成一个强大的类似于Matlab的科学计算环境,有助于我们通过 Python 学习数据科学或者机器学习。在Python中,当你定义了一个numpy类型的数组后,它内部元素的真实地址如何获得呢?

27de70ca7d9fe5ca18f16a2fc1edf64b.png

这里可以通过numpy数组的“__array_interface__”接口得到。

比如下面的例子:

import numpy as np 
from ctypes import * 
a = np.array([1, 2, 3, 4, 5], dtype=np.uint8) 
print(a.__array_interface__['data']) 

上面程序定义了一个numpy类型的数组a,运行后得到:

(1883707159072, False) 

接口“__array_interface__”返回一个包含两个元素的元组,其第1个元素即为a数组内部元素存放的真实地址,第2个元素标明了该数组是否为“只读”属性。

2、如何与ctypes库创建的数组共享内存空间?

对于Python编程人员来说,ctypes库也是使用率比较高的一个库,当调用第三方提供的动态库链接库函数时,它经常用于定义与C语言兼容的数据类型变量,作为Python语言与C语言进行数据交互的桥梁。

9786dd7298193785125fe3fa53bd601b.png

那么,如何使用ctypes库定义一个与numpy共享内存空间的数组变量呢?

仍以上面的例子,定义一个uint8类型的数组b,与a数组共享内存区域,可使用下面的代码:

b = (c_uint8*len(a)).from_address(a.__array_interface__['data'][0]) 
print('a =', a, 'nb =', b[:]) 

运行后得到:

a = [1 2 3 4 5]  
b = [1, 2, 3, 4, 5] 

可见,使用ctypes库的from_address函数定义了一个与a同地址的数组b,打印出b的元素值后,其初始元素值确实与数组a相同。

下面验证一下,数组a和b里面的元素是否真正的占用同一个内存区域。

先改变数组a中第1个元素的值,运行下面的代码:

a[0] = 10 
print('a =', a, 'nb =', b[:]}]) 

其运行结果为:

a = [10  2  3  4  5]  
b = [10, 2, 3, 4, 5] 

可见,将数组a中的第一个元素的值由1改成10后,b数组中第一个元素也同步改变成10了。

紧接着,再改变b数组中第二个元素的值,由2改为20:

b[1] = 20 
print('a =', a, 'nb =', b[:]) 

其运行结果为:

a = [10 20  3  4  5]  
b = [10, 20, 3, 4, 5] 

显然,数组a中第二个元素的值也同步改变为20了。

因此,数组a与数组b确实是占用的同一个内存地址空间。

另外,也可以通过数组b再定义一个与b共享内存区域的numpy数组c,使用下面的代码即可:

c = np.frombuffer(b, dtype=np.uint8) 

可以自行验证数组a、b、c是否为同一个内存空间。

3、结论

上面的例子表明,在Python编程中,numpy类型的数组与ctypes类型的数组可以进行互换,比如,可以使用numpy库进行复杂的运算后,再转换成ctypes类型的数组,传递到第3方的动态库dll函数中作进一步的处理,这样,在某些场合下,既能使用numpy库的强大运算功能,又可以使用第三方库,来实现我们特定的处理需求。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值