将字节分配给 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 只是让它更有效率。