Python 如何展平记忆视图?
我有一个Python 如何展平记忆视图?,python,memoryview,Python,Memoryview,我有一个memoryview,步幅很小,如下所示: >>> mv.strides (96, 32, 8) 我想将此memoryview写入套接字,但我的网络库似乎希望memoryview具有mv.strips==(1,)。Python中有没有办法将这个内存视图展平 >>> flatten(mv).strides (1,) 理想情况下,这既不会影响底层字节,也不需要副本。我可以用NumPy来做这件事,但如果可能的话,我更愿意把事情概括起来 编辑:下面是一些生
memoryview
,步幅很小,如下所示:
>>> mv.strides
(96, 32, 8)
我想将此memoryview
写入套接字,但我的网络库似乎希望memoryview具有mv.strips==(1,)
。Python中有没有办法将这个内存视图展平
>>> flatten(mv).strides
(1,)
理想情况下,这既不会影响底层字节,也不需要副本。我可以用NumPy来做这件事,但如果可能的话,我更愿意把事情概括起来
编辑:下面是一些生成这样一个memoryview的代码
[1]中的:将numpy作为np导入
在[2]中:x=np.one((2,3,4))
在[3]:x.data中
出[3]:
在[4]中:x.data.strips
Out[4]:(96,32,8)
为了澄清,您可能知道这一点,但我认为最好确保:
- 跨步元组的长度表示维度的数量,因此
(1,)
和(8,)
都是一维的,(10,2)
和(20,1)
都是二维的
- 对于C-连续数组,步长元组中的最后一个元素表示memoryview中项目的itemsize。这并不总是正确的:有时填充的值会比实际的itemsize大——但在大多数情况下,它表示itemsize
因此,您不仅希望将memoryview展平,还应该将其展平,并将itemsize设置为1
在Python 3.3中,添加了使数组平坦化变得微不足道的方法:
cast(格式[,形状])
将记忆视图转换为新格式或形状。shape默认为[byte\u length//new\u itemsize],这意味着结果视图将是一维的。返回值是一个新的memoryview,但不会复制缓冲区本身。支持的强制转换为1D->C-连续和C-连续->1D
目标格式限制为结构语法中的单个元素本机格式。其中一种格式必须是字节格式(“B”、“B”或“c”)。结果的字节长度必须与原始长度相同
因此,只有当您强制转换为char(c
)、无符号char(B
)或有符号char(B
)并且它是c-连续的时,它才起作用
>>> import numpy as np
>>> memview = memoryview(np.ones((2, 3, 4)))
>>> memview.cast('b').strides # or 'B' or 'c'
(1, )
但是,这是平坦的,并解释为1字节值。如果您只想将其展平,则需要再次将其转换为原始类型:
>>> memview.cast('b').cast(memview.format)
这将是一维的,但不会有(1,)
的跨步,因为浮点是8字节(至少如果是float64
):
此内存视图的来源是什么?这不是一个基本的Python类或概念。我只知道cython的这个术语。@hpaulj这是一个python概念:。但最好能确切地知道memoryview
我们在谈论什么,memoryview确实是Python的一部分。数字社区通常使用它们。我的用户通常会根据numpy计算结果提供它们,但我更喜欢不以numpy为中心的解决方案。如果您不想要以numpy为中心的答案,请添加只使用Python内置内容创建答案的代码。一系列cast
调用使用非字节格式:x.data.cast('B').cast('B',shape=[192]).cast('d')
。但是'd'的跨步是(8,)
。所以(1,)
的跨步需要兼容的格式。@hpaulj是的,但是使用.cast('B').cast(memview.format)
更容易。这样就不需要指定形状了。
>>> memview.cast('b').cast(memview.format)
>>> memview.cast('b').cast(memview.format).strides
(8, )