你所追求的在 Cython 中是不可能的。如果你想要一些表现良好的东西,我可能会创建一个 C 结构,其中包含来自 memoryview 的相关信息,然后改用它。这不是一个非常优雅的解决方案,但它会提供与使用 memoryviews 类似的性能;我不建议将其作为一种常见模式,但如果您的数据需要一次性解决问题,那么就可以了。
cdef struct FakeMemoryView:
int* data
int stride
int length
如果您准备强制使用 C 个连续的 memorviews ( int[::1]
),那么您可以放弃stride
,因为它会被认为是一个。可以使用 索引数据var.data[i*var.stride]
。在您的函数开始时,您循环遍历您的 Python 列表以创建这些FakeMemoryView
s 的数组,然后从那时起您只需使用此数组:
def function1(list list_of_numpy_arrays):
assert len(list_of_numpy_arrays) == 5
cdef FakeMemoryView new_list[5]
# initialize the list
cdef int[:] mview
for i in range(5):
mview = list_of_numpy_arrays[i]
new_list[i].data = &mview[0]
new_list[i].stride = mview.strides[0]
new_list[i].length = mview.shape[0]
# example access - zero the first lot of data
for i in range(new_list[0].length):
new_list[0].data[i*new_list[0].stride] = 0
如果您事先不知道列表的长度,那么您需要使用malloc
and自己处理内存free
。
此解决方案不处理对 Numpy 数组进行引用计数 - 因此您不应允许在持有FakeMemoryView
s 时释放 Numpy 数组。不要为多个函数调用存储数组,也不要开始从输入列表中删除数组。