我的函数接收一系列不同大小的numpy数组:
def function1(list list_of_numpy_arrays):
现在我正在做
cdef int[:] a_view = list_of_numpy_arrays[index]
问题是我必须索引列表很多次,因此开销大大增加了时间(10x)。我正在寻找类似cdef int[:] a[5]
的东西,在这里可以有一个内存视图数组,这样可以避免索引python列表的开销。
如果有解决方案,我也可以传递列表列表。
def function2(list list_of_lists):
答案 0 :(得分:3)
在Cython中,您真正追求的是不可能的。如果您想要性能良好的东西,我可能会创建一个C结构,其中包含来自memoryview的相关信息,然后使用它。这不是一个非常优雅的解决方案,但是它将提供与使用memoryviews类似的性能。我不建议将其设置为通用模式,但是如果您遇到数据需要一次性输入的问题,那就可以了。
cdef struct FakeMemoryView:
int* data
int stride
int length
如果您准备强制执行C个连续的记忆视图(int[::1]
),则可以放弃stride
,因为它被认为是一个。可以使用var.data[i*var.stride]
为数据建立索引。在函数开始时,您遍历Python列表以创建包含这些FakeMemoryView
的数组,然后从这一点开始,您只需使用以下数组:
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
和free
自己处理列表的内存。
此解决方案不处理对Numpy数组进行引用计数的操作-因此,在保存FakeMemoryView
时,您不应允许Numpy数组被释放。不要在数组中存储多个函数调用,也不要从输入列表中删除数组。