Python 在Cython中创建长度不等的numpy.ndarray列表
我现在有了python代码来创建Ndarray列表,这些数组的长度不相等。这段代码片段如下所示:Python 在Cython中创建长度不等的numpy.ndarray列表,python,arrays,object,numpy,cython,Python,Arrays,Object,Numpy,Cython,我现在有了python代码来创建Ndarray列表,这些数组的长度不相等。这段代码片段如下所示: import numpy as np from mymodule import list_size, array_length # list_size and array_length are two lists of ints, and the len(array_length) == list_size ndarray_list = [] for i in range(list_size):
import numpy as np
from mymodule import list_size, array_length # list_size and array_length are two lists of ints, and the len(array_length) == list_size
ndarray_list = []
for i in range(list_size):
ndarray_list.append(np.zeros(array_length[i]))
import numpy as np
cimport numpy as np
from mymodule import list_size, array_length
cdef int i
ndarray_list = <double **>malloc(list_size * sizeof(double*))
for i in range(list_size):
ndarray_list[i] = <double *>malloc(array_length[i] * sizeof(double))
现在,我需要将其转换为Cython,但不知道如何转换。我尝试创建一个二维动态分配数组,如下所示:
import numpy as np
from mymodule import list_size, array_length # list_size and array_length are two lists of ints, and the len(array_length) == list_size
ndarray_list = []
for i in range(list_size):
ndarray_list.append(np.zeros(array_length[i]))
import numpy as np
cimport numpy as np
from mymodule import list_size, array_length
cdef int i
ndarray_list = <double **>malloc(list_size * sizeof(double*))
for i in range(list_size):
ndarray_list[i] = <double *>malloc(array_length[i] * sizeof(double))
将numpy导入为np
cimport numpy作为np
从mymodule导入列表\u大小、数组\u长度
cdef int i
ndarray\u list=malloc(list\u size*sizeof(double*))
对于范围内的i(列表大小):
ndarray_list[i]=malloc(数组长度[i]*sizeof(双精度))
但是,此方法仅在ndarray_列表[i]中创建一个双指针。我无法将其传递给其他需要ndarray方法的函数
我该怎么办?您可以将
对象
类型与基于NumPy的缓冲区一起使用。要有效地填充ndarray\u列表
,您只需要一个对象
缓冲区,但请注意,对np.zeros()
的许多调用可能会导致一些缓慢:
cdef int i, list_size
cdef np.ndarray[np.int_t, ndim=1] array_length
cdef np.ndarray[object, ndim=1] ndarray_list
list_size = 10000
array_length = np.arange(list_size).astype(np.int)+1
ndarray_list = np.empty(list_size, dtype=object)
for i in range(list_size):
ndarray_list[i] = np.zeros(array_length[i], dtype=np.float64)
要高效访问内部阵列,您需要另一个一维缓冲区:
cdef np.ndarray[np.float64_t, ndim=1] inner_array
cdef double test
cdef int j
for i in range(list_size):
inner_array = ndarray_list[i]
for j in range(inner_array.shape[0]):
test = inner_array[j]
为了将C
double*
缓冲区传递给需要numpy.ndarray
的函数,您可以创建一个临时缓冲区,并将double*
数组的地址分配给它的内存地址
这个基于malloc()
的解决方案比另一个基于NumPy缓冲区的解决方案快几个数量级。注意如何free()
内部数组以避免内存泄漏
import numpy as np
cimport numpy as np
from cython cimport view
from libc.stdlib cimport malloc, free
cdef int i
cdef double test
list_size = 10
ndarray_list = <double **>malloc(list_size * sizeof(double*))
array_length = <int *>malloc(list_size * sizeof(int*))
for i in range(list_size):
array_length[i] = i+1
ndarray_list[i] = <double *>malloc(array_length[i] * sizeof(double))
for j in range(array_length[i]):
ndarray_list[i][j] = j
for i in range(list_size):
for j in range(array_length[i]):
test = ndarray_list[i][j]
cdef view.array buff
for i in range(list_size):
buff = <double[:array_length[i]]>ndarray_list[i]
print np.sum(buff)
#...
for i in range(list_size):
free(ndarray_list[i])
free(ndarray_list)
free(array_length)
将numpy导入为np
cimport numpy作为np
从cython cimport视图
来自libc.stdlib cimport malloc,免费
cdef int i
cdef双重测试
列表大小=10
ndarray\u list=malloc(list\u size*sizeof(double*))
数组长度=malloc(列表大小*sizeof(int*))
对于范围内的i(列表大小):
数组长度[i]=i+1
ndarray_list[i]=malloc(数组长度[i]*sizeof(双精度))
对于范围内的j(数组长度[i]):
ndarray_list[i][j]=j
对于范围内的i(列表大小):
对于范围内的j(数组长度[i]):
测试=数据列表[i][j]
cdef view.array buff
对于范围内的i(列表大小):
buff=ndarray_列表[i]
打印np.总和(浅黄色)
#...
对于范围内的i(列表大小):
免费(ndarray_列表[i])
免费(ndarray_列表)
自由(数组长度)
我试图将这两种方法浓缩到一个答案中,但将其分成两部分看起来要好得多。。。您使用buff.data
被转换为
?是不是应该是
?@ShawnWang这是我第一次尝试,但我得到无法将类型“double*”分配给“char*”
,然后我使用了char*
,我没有找到任何解释为什么我们必须使用char*
的参考资料,谢谢Saullo!这真的很有趣。。。我尝试了void*
,但也不起作用。好吧,至少我们让它工作了。再次感谢!:)@ShawnWang我正试图找到一个更好的方法来做到这一点。。。无需调用np.empty()
并使用此char*
cast…@ShawnWang,我发现了一种非常简单的方法,可以使用Cython数组以更干净的方式执行此操作。。。检查更新。。。