我很少使用frombuffer
,但我认为np.array
与传统构建的数组一样适用于这些数组。
每个column_data
数组都有自己的数据缓冲区 - 你分配了它的mmap。但是np.array(columns)
从列表中读取每个数组的值,并从它们构造一个新的数组,该数组具有自己的数据缓冲区。
我喜欢使用x.__array_interface__
查看数据缓冲区位置(以及查看其他关键属性)。将columns
的每个元素和data
的字典进行比较。
你可以使用连续块从mmap构造2d数组。只需创建1d的frombuffer
数组,然后对其进行reshape
。甚至transpose
也将继续使用该缓冲区(使用F
顺序)。切片和视图也使用它。
但是,除非你非常小心,否则很快就会得到将数据放在其他地方的副本。只需使用 data1 = data+1
就可以创建一个新数组,或者使用高级索引 data[[1,3,5],:]
。任何连接
都是一样的。
从字节串缓冲区获取2个数组:
In [534]: x=np.frombuffer(b'abcdef',np.uint8)
In [535]: y=np.frombuffer(b'ghijkl',np.uint8)
通过将它们连接起来创建一个新的数组。
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)
x,y,z
的数据缓冲区位置完全不同
但是重塑后的x
数据没有改变
In [541]: x.reshape(2,3).__array_interface__['data']
Out[541]: (3013090040, True)
也不进行二维转置
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}
相同的数据,不同的视图。
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')