为了账号安全,请及时绑定邮箱和手机立即绑定

在纯 Python 中转置“memoryview”

在纯 Python 中转置“memoryview”

白衣非少年 2022-12-20 14:26:02
是否有纯 Python 方法来转置 a memoryview?Python memoryviews可以表示的不仅仅是一维字节块。它们可以表示多维布局、非连续内存、复杂元素类型等。例如,在下面的代码中:In [1]: import numpyIn [2]: x = numpy.array([[1, 2], [3, 4]])In [3]: y = x.TIn [4]: a = memoryview(x)In [5]: b = memoryview(y)a并且b是 2×2 多维内存视图:In [6]: a.shapeOut[6]: (2, 2)In [7]: b.shapeOut[7]: (2, 2)andb表示 的转置a,soa[i, j]和b[j, i]alias 相同的内存(即原始x数组的单元格 i、j):In [8]: a[0, 1] = 5In [9]: b[1, 0]Out[9]: 5In [10]: xOut[10]: array([[1, 5],       [3, 4]])NumPy 数组支持简单的转置,但 NumPy 数组并不是多维内存视图的唯一来源。例如,您可以投射一维内存视图:In [11]: bytearr = bytearray([1, 2, 3, 4])In [12]: mem = memoryview(bytearr).cast('b', (2, 2))In [13]: mem.shapeOut[13]: (2, 2)In [14]: mem[1, 0] = 5In [15]: bytearrOut[15]: bytearray(b'\x01\x02\x05\x04')memoryview 格式非常灵活,可以表示 的转置mem,就像我们b之前a示例中的转置一样,但在 memoryview API 中似乎没有简单的转置方法。是否有转置任意多维内存视图的纯 Python 方法?
查看完整描述

2 回答

?
扬帆大鱼

TA贡献1799条经验 获得超9个赞

不依赖就没有好办法。使用 NumPy,它非常简单,只要 memoryview 没有子偏移量:


transposed = memoryview(numpy.asarray(orig_memoryview).T)

orig_memoryview可以由任何东西支持——它后面不必有 NumPy 数组。


与其他答案不同,生成的内存视图由与原始内存视图相同的内存支持。例如,使用以下多维内存视图:


In [1]: import numpy


In [2]: arr = numpy.array([[1, 2], [3, 4]])


In [3]: mem = memoryview(arr)

我们可以转置它:


In [4]: transposed = memoryview(numpy.asarray(mem).T)

并写入转置内存视图会影响原始数组:


In [5]: transposed[0, 1] = 5


In [6]: arr

Out[6]: 

array([[1, 2],

       [5, 4]])

此处,写入转置的单元格 0、1 对应于原始数组的单元格 1、0。


这不依赖于由 NumPy 数组支持的原始内存视图。它适用于由其他东西支持的内存视图,比如bytearrays:


In [7]: x = bytearray([1, 2, 3, 4])


In [8]: y = memoryview(x).cast('b', (2, 2))


In [9]: transposed = memoryview(numpy.asarray(y).T)


In [10]: transposed[0, 1] = 5


In [11]: y[1, 0]

Out[11]: 5


In [12]: x

Out[12]: bytearray(b'\x01\x02\x05\x04')

没有 NumPy 或类似的依赖项,我看不出什么好方法。最接近好方法的是使用 ctypes,但您需要为此硬编码Py_buffer结构布局,并且Py_buffer结构的确切布局没有记录。(字段顺序和类型与记录字段的顺序或记录它们的类型不完全匹配。)此外,对于具有子偏移量的PIL 样式数组,如果不复制就无法转置内存视图数据。


从好的方面来说,大多数情况下你要处理多维内存视图,你已经有了转置它们所需的依赖关系。


查看完整回答
反对 回复 2022-12-20
?
蝴蝶刀刀

TA贡献1801条经验 获得超8个赞

这可能会帮助您:


>>> import numpy as np

>>> import array

>>> a = array.array('l', [-11111111, 22222222, -33333333, 44444444])

>>> m = memoryview(a)

>>> m_copy =  np.array(m)[np.newaxis]

>>> m_copy

array([[-11111111,  22222222, -33333333,  44444444]])

>>> m_copy.T

array([[-11111111],

       [ 22222222],

       [-33333333],

       [ 44444444]])


不使用 numpy:


import array

a = array.array('l', [-11111111, 22222222, -33333333, 44444444])

print(a)


#output:

array('l', [-11111111, 22222222, -33333333, 44444444])


m = memoryview(a)

a = [[x for x in m]]

result = list(map(list, zip(*a)))

print(result)


#output:

[[-11111111], [22222222], [-33333333], [44444444]]


查看完整回答
反对 回复 2022-12-20
  • 2 回答
  • 0 关注
  • 132 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号