将字节分配给 Cython 内存视图
Assign bytes to Cython memory view
我有一个二维 Cython 数组的内存视图,定义为
cdef unsigned char[:,:] store = view.array(
shape=(n, 141),
itemsize=sizeof(unsigned char),
format="B",
)
,其中 n
是我拥有的“行”数。为了示例,我们假设 n=2
。每行都是一个大小为 141 的 Python 字节对象,我在 bytes
:
列表中
rows = [
b"4612edc38e7acc81520860b210c4ae7a14ace72bbb710514bd5ef71bb96e7af55b307580b015efac3cb84339fa9ff99401ed6fe211bb75b937fa575fc3928500c511aee084e5c",
b"beb71c68b420fcb093d7c5894d726239bb0620229e46f91c11d3c2cd688e37c0c279ec844152cf87ea6c3f6915ac90aeb83ade44dfe22b1ae9c6fdd87e813eed98e5faca4d250",
]
我现在想将这些行中的数据移动到内存视图中。目前,我正在以一种相当愚蠢的方式这样做:
for i, row in enumerate(rows):
for j, byte_ in enumerate(row):
store[i, j] = byte_
虽然这行得通,但我认为它效率低下(除非 cythonize
施展魔法来摆脱循环),而且看起来凌乱且过于复杂。我希望能够简单地做类似的事情:
store[:,:] = rows
或者,至少:
for i, row in enumerate(rows):
store[i, :] = row # fails with TypeError: an integer is required
遗憾的是,none 有效。我还尝试了以下方法:
# fails because the resulting number is a bigint (?)
store[i, :] = int.from_bytes(bytearray, sys.byteorder)
# fails with TypeError: an integer is required
store[i, :] = np.array(list(row))
一定有更好的方法。我错过了什么?
以下作品:
cdef const unsigned char[::1] row
for i, row in enumerate(rows):
store[i, :] = row
本质上,如果它知道该行是内存视图,它只能执行切片的“逐个元素”复制。否则它假定 row 是切片应该填充的单个值。
我使用了 const unsigned char[::1]
,因为字节对象是不可变且连续的。没有 const
它不会编译,而 ::1
只是让它更有效率。
我有一个二维 Cython 数组的内存视图,定义为
cdef unsigned char[:,:] store = view.array(
shape=(n, 141),
itemsize=sizeof(unsigned char),
format="B",
)
,其中 n
是我拥有的“行”数。为了示例,我们假设 n=2
。每行都是一个大小为 141 的 Python 字节对象,我在 bytes
:
rows = [
b"4612edc38e7acc81520860b210c4ae7a14ace72bbb710514bd5ef71bb96e7af55b307580b015efac3cb84339fa9ff99401ed6fe211bb75b937fa575fc3928500c511aee084e5c",
b"beb71c68b420fcb093d7c5894d726239bb0620229e46f91c11d3c2cd688e37c0c279ec844152cf87ea6c3f6915ac90aeb83ade44dfe22b1ae9c6fdd87e813eed98e5faca4d250",
]
我现在想将这些行中的数据移动到内存视图中。目前,我正在以一种相当愚蠢的方式这样做:
for i, row in enumerate(rows):
for j, byte_ in enumerate(row):
store[i, j] = byte_
虽然这行得通,但我认为它效率低下(除非 cythonize
施展魔法来摆脱循环),而且看起来凌乱且过于复杂。我希望能够简单地做类似的事情:
store[:,:] = rows
或者,至少:
for i, row in enumerate(rows):
store[i, :] = row # fails with TypeError: an integer is required
遗憾的是,none 有效。我还尝试了以下方法:
# fails because the resulting number is a bigint (?)
store[i, :] = int.from_bytes(bytearray, sys.byteorder)
# fails with TypeError: an integer is required
store[i, :] = np.array(list(row))
一定有更好的方法。我错过了什么?
以下作品:
cdef const unsigned char[::1] row
for i, row in enumerate(rows):
store[i, :] = row
本质上,如果它知道该行是内存视图,它只能执行切片的“逐个元素”复制。否则它假定 row 是切片应该填充的单个值。
我使用了 const unsigned char[::1]
,因为字节对象是不可变且连续的。没有 const
它不会编译,而 ::1
只是让它更有效率。