假设我有一个1/(1e-16 + sin(pi))
字典,我想从字典本身创建这个数据的numpy视图。例如:
__array_interface__
但是,这不起作用,因为buff = {'shape': (3, 3), 'data': (140546686381536, False), 'typestr': '<f8'}
view = np.array(buff, copy=False)
搜索缓冲区或数组接口作为属性。简单的解决方法可能如下:
np.array
这似乎有点迂回。我错过了直截了当的方法吗?
答案 0 :(得分:4)
更正 - 使用正确的“数据”值,holder
适用于np.array
:
np.array
肯定不会起作用,因为它需要一个可迭代的,一些像列表的列表,并解析各个值。
有一个低级构造函数np.ndarray
,它接受一个缓冲区参数。还有np.frombuffer
。
但我的印象是x.__array_interface__['data'][0]
是数据缓冲区位置的整数表示,但不是直接指向缓冲区的指针。我只用它来验证视图是否共享相同的数据缓冲区,而不是从它构造任何东西。
np.lib.stride_tricks.as_strided
使用__array_interface__
作为默认的步幅和形状数据,但是从数组中获取数据,而不是__array_interface__
字典。
===========
具有ndarray
属性的.data
示例:
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])
这两个数组都是视图。
好的,使用holder
类,我可以使用此res.data
作为数据缓冲区来做同样的事情。您的班级会创建object exposing the array interface
。
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]])
答案 1 :(得分:0)
这是另一种方法:
import numpy as np
def arr_from_ptr(pointer, typestr, shape, copy=False,
read_only_flag=False):
"""Generates numpy array from memory address
https://docs.scipy.org/doc/numpy-1.13.0/reference/arrays.interface.html
Parameters
----------
pointer : int
Memory address
typestr : str
A string providing the basic type of the homogenous array The
basic string format consists of 3 parts: a character
describing the byteorder of the data (<: little-endian, >:
big-endian, |: not-relevant), a character code giving the
basic type of the array, and an integer providing the number
of bytes the type uses.
The basic type character codes are:
- t Bit field (following integer gives the number of bits in the bit field).
- b Boolean (integer type where all values are only True or False)
- i Integer
- u Unsigned integer
- f Floating point
- c Complex floating point
- m Timedelta
- M Datetime
- O Object (i.e. the memory contains a pointer to PyObject)
- S String (fixed-length sequence of char)
- U Unicode (fixed-length sequence of Py_UNICODE)
- V Other (void * – each item is a fixed-size chunk of memory)
See https://docs.scipy.org/doc/numpy-1.13.0/reference/arrays.interface.html#__array_interface__
shape : tuple
Shape of array.
copy : bool
Copy array. Default False
read_only_flag : bool
Read only array. Default False.
"""
buff = {'data': (pointer, read_only_flag),
'typestr': typestr,
'shape': shape}
class numpy_holder():
pass
holder = numpy_holder()
holder.__array_interface__ = buff
return np.array(holder, copy=copy)
用法:
# create array
arr = np.ones(10)
# grab pointer from array
pointer, read_only_flag = arr.__array_interface__['data']
# constrct numpy array from an int pointer
arr_out = arr_from_ptr(pointer, '<f8', (10,))
# verify it's the same data
arr[0] = 0
assert np.allclose(arr, arr_out)