Numpy 2D-缓冲区中的数组?

Chr*_*uer 5 python numpy

我有一个内存映射,其中包含一个 2D 数组,我想从中创建一个 numpy 数组。理想情况下,我想避免复制,因为涉及的数组可能很大。

我的代码如下所示:

n_bytes = 10000
tagname = "Some Tag from external System"
map = mmap.mmap(-1, n_bytes, tagname)
offsets = [0, 5000]

columns = []
for offset in offsets:
   #type and count vary in the real code, but for this dummy code I simply made them up. But I know the count and type for every column.
   np_type = np.dtype('f4')
   column_data = np.frombuffer(map, np_type, count=500, offset=offset)
   columns.append(column_data)

# this line seems to copy the data, which I would like to avoid
data = np.array(columns).T
Run Code Online (Sandbox Code Playgroud)

Ita*_*Gal 6

假设您有一个字节数组并且您知道它的尺寸,那么答案非常简单。想象一下,缓冲区(名为“buff”)中图像的原始 RGB 数据(每像素 24 位)尺寸为 1024x768

#read the buffer into 1D byte array
arr = numpy.frombuffer(buff, dtype=numpy.uint8)
#now shape the array as you please
arr.shape = (768,1024,3)
Run Code Online (Sandbox Code Playgroud)


hpa*_*ulj 1

我没有使用frombuffer太多,但我认为np.array这些数组的工作方式与传统构造的数组一样。

每个column_data数组都有自己的数据缓冲区 - 您分配给它的 mmap。但是np.array(columns)从列表中的每个数组中读取值,并用它们自己的数据缓冲区构造一个新数组。

我喜欢用它x.__array_interface__来查看数据缓冲区位置(并查看其他关键属性)。比较该字典中的每个元素columns和 for data

您可以使用连续的块从 mmap 构造二维数组。只需制作一维frombuffer数组即可reshape。Eventranspose将继续使用该缓冲区(按F顺序)。切片和视图也使用它。

但除非您非常小心,否则您很快就会得到将数据放在其他地方的副本。简单地data1 = data+1创建一个新数组,或者提前索引data[[1,3,5],:]。对于任何 都一样concatenation

来自字节串缓冲区的 2 个数组:

In [534]: x=np.frombuffer(b'abcdef',np.uint8)
In [535]: y=np.frombuffer(b'ghijkl',np.uint8)
Run Code Online (Sandbox Code Playgroud)

通过加入它们来创建一个新数组

In [536]: z=np.array((x,y))

In [538]: x.__array_interface__
Out[538]: 
{'data': (3013090040, True),
 'descr': [('', '|u1')],
 'shape': (6,),
 'strides': None,
 'typestr': '|u1',
 'version': 3}
In [539]: y.__array_interface__['data']
Out[539]: (3013089608, True)
In [540]: z.__array_interface__['data']
Out[540]: (180817384, False)
Run Code Online (Sandbox Code Playgroud)

的数据缓冲区位置x,y,z完全不同

但重塑后的数据x并没有改变

In [541]: x.reshape(2,3).__array_interface__['data']
Out[541]: (3013090040, True)
Run Code Online (Sandbox Code Playgroud)

2d 也不转置

In [542]: x.reshape(2,3).T.__array_interface__
Out[542]: 
{'data': (3013090040, True),
 'descr': [('', '|u1')],
 'shape': (3, 2),
 'strides': (1, 3),
 'typestr': '|u1',
 'version': 3}
Run Code Online (Sandbox Code Playgroud)

相同的数据,不同的视图

In [544]: x
Out[544]: array([ 97,  98,  99, 100, 101, 102], dtype=uint8)
In [545]: x.reshape(2,3).T
Out[545]: 
array([[ 97, 100],
       [ 98, 101],
       [ 99, 102]], dtype=uint8)
In [546]: x.reshape(2,3).T.view('S1')
Out[546]: 
array([[b'a', b'd'],
       [b'b', b'e'],
       [b'c', b'f']], 
      dtype='|S1')
Run Code Online (Sandbox Code Playgroud)