Python 直接从_数组_接口创建NumPy数组__

Python 直接从_数组_接口创建NumPy数组__,python,numpy,pybinding,Python,Numpy,Pybinding,假设我有一个\uuuuu数组\uu接口\uuuuu字典,我想从字典本身创建此数据的numpy视图。例如: buff = {'shape': (3, 3), 'data': (140546686381536, False), 'typestr': '<f8'} view = np.array(buff, copy=False) 这似乎有点迂回。我是否缺少一种简单的方法来实现这一点?更正-使用正确的“数据”值,您的持有者在np.数组中工作: np.array肯定不起作用,因为它需要一个ite

假设我有一个
\uuuuu数组\uu接口\uuuuu
字典,我想从字典本身创建此数据的numpy视图。例如:

buff = {'shape': (3, 3), 'data': (140546686381536, False), 'typestr': '<f8'}
view = np.array(buff, copy=False)

这似乎有点迂回。我是否缺少一种简单的方法来实现这一点?

更正-使用正确的“数据”值,您的
持有者
np.数组中工作:

np.array
肯定不起作用,因为它需要一个iterable,比如一个列表列表,并解析各个值

有一个低级构造函数,
np.ndarray
,它接受一个缓冲区参数。和一个
np.frombuffer

但我的印象是,
x.\uuuu数组\u接口\uuu['data'][0]
是数据缓冲区位置的整数表示,而不是直接指向缓冲区的指针。我只是用它来验证一个视图是否共享同一个数据缓冲区,而不是用它来构造任何东西

np.lib.stride\u技巧。as\u stride
使用
\uuuu数组接口\uuuu
作为默认步幅和形状数据,但从数组而不是
\uu数组接口\uuuu
字典获取数据

===========

带有
.data
属性的
ndarray
示例:

In [303]: res
Out[303]: 
array([[ 0, 20, 50, 30],
       [ 0, 50, 50,  0],
       [ 0,  0, 75, 25]])
In [304]: res.__array_interface__
Out[304]: 
{'data': (178919136, False),
 'descr': [('', '<i4')],
 'shape': (3, 4),
 'strides': None,
 'typestr': '<i4',
 'version': 3}
In [305]: res.data
Out[305]: <memory at 0xb13ef72c>
In [306]: np.ndarray(buffer=res.data, shape=(4,3),dtype=int)
Out[306]: 
array([[ 0, 20, 50],
       [30,  0, 50],
       [50,  0,  0],
       [ 0, 75, 25]])
In [324]: np.frombuffer(res.data,dtype=int)
Out[324]: array([ 0, 20, 50, 30,  0, 50, 50,  0,  0,  0, 75, 25])

以下是另一种方法:

将numpy导入为np
def arr_from_ptr(指针、typestr、形状、副本=False,
只读标志=假):
“”“从内存地址生成numpy数组。”
https://docs.scipy.org/doc/numpy-1.13.0/reference/arrays.interface.html
参数
----------
指针:int
存储器地址
类型str:str
提供同质数组的基本类型的字符串
基本字符串格式由3部分组成:一个字符
描述数据的字节顺序(:
big-endian,|:不相关),给出
数组的基本类型,以及提供数字的整数
类型使用的字节数。
基本类型字符代码为:
-t位字段(以下整数给出位字段中的位数)。
-b布尔值(整数类型,其中所有值仅为真或假)
-i整数
-无符号整数
-f浮点
-c复数浮点
-m时间增量
-M日期时间
-O对象(即内存中包含指向PyObject的指针)
-S字符串(字符的固定长度序列)
-U Unicode(Py_Unicode的固定长度序列)
-V Other(void*–每个项都是固定大小的内存块)
看见https://docs.scipy.org/doc/numpy-1.13.0/reference/arrays.interface.html#__array_interface__
形状:元组
阵列的形状。
抄送:布尔
复制数组。默认值为False
只读标志:bool
只读数组。默认值为False。
"""
buff={'data':(指针,只读标志),
“typestr”:typestr,
“形状”:形状}
类numpy_holder():
通过
holder=numpy_holder()
保持架。\阵列\接口\增益=增益
返回np.数组(持有者,副本=副本)
用法:

#创建数组
arr=np.ones(10)
#从数组中获取指针
指针,只读\u标志=arr.\u数组\u接口\u['data']
#从int指针构造numpy数组

调出=调出调出调出(指针)“你的工作是否工作,或者你只是推测?为什么你只有DICT?你手动创建它来暴露一个数组吗?我肯定只把DICT粘贴到包装对象上,就像你在这里做的一样,虽然可能有一个C++代码。Re
data[0]
是缓冲区指针的表示形式。您说得对,可能还希望使用视图(而不是副本)包含numpy文档指针而不是Python的缓冲区接口指向的数据可能会导致内存泄漏问题。也就是说,如果原始所有者不在范围内,缓冲区接口允许其他用户保持缓冲区的活动状态。(希望有意义:s)Python/NuMy是什么版本?我为缓冲区带来了一个类型错误。@沙尔斯ID指出,这种技术的一个很大的优点是它是一个视图。这允许你用Python和NoMpy来操纵C++数据。你不能真正地获得内存泄漏,但是你可以得到无效的访问。这通常是由智能包处理的。ping和智能指针。
In [303]: res
Out[303]: 
array([[ 0, 20, 50, 30],
       [ 0, 50, 50,  0],
       [ 0,  0, 75, 25]])
In [304]: res.__array_interface__
Out[304]: 
{'data': (178919136, False),
 'descr': [('', '<i4')],
 'shape': (3, 4),
 'strides': None,
 'typestr': '<i4',
 'version': 3}
In [305]: res.data
Out[305]: <memory at 0xb13ef72c>
In [306]: np.ndarray(buffer=res.data, shape=(4,3),dtype=int)
Out[306]: 
array([[ 0, 20, 50],
       [30,  0, 50],
       [50,  0,  0],
       [ 0, 75, 25]])
In [324]: np.frombuffer(res.data,dtype=int)
Out[324]: array([ 0, 20, 50, 30,  0, 50, 50,  0,  0,  0, 75, 25])
In [379]: holder=numpy_holder()
In [380]: buff={'data':res.data, 'shape':(4,3), 'typestr':'<i4'}
In [381]: holder.__array_interface__ = buff
In [382]: np.array(holder, copy=False)
Out[382]: 
array([[ 0, 20, 50],
       [30,  0, 50],
       [50,  0,  0],
       [ 0, 75, 25]])