Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在Cython中创建长度不等的numpy.ndarray列表_Python_Arrays_Object_Numpy_Cython - Fatal编程技术网

Python 在Cython中创建长度不等的numpy.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):

我现在有了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):
    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_列表)
自由(数组长度)

我试图将这两种方法浓缩到一个答案中,但将其分成两部分看起来要好得多。。。您使用 MalCube()/代码>的方法的数量级要快一些,所以您应该考虑<代码> MalCube()/基于代码>的答案……非常感谢Saullo Castro的精彩解答!理解代码的一个简单问题是:为什么
buff.data
被转换为
?是不是应该是
?@ShawnWang这是我第一次尝试,但我得到
无法将类型“double*”分配给“char*”
,然后我使用了
char*
,我没有找到任何解释为什么我们必须使用
char*
的参考资料,谢谢Saullo!这真的很有趣。。。我尝试了
void*
,但也不起作用。好吧,至少我们让它工作了。再次感谢!:)@ShawnWang我正试图找到一个更好的方法来做到这一点。。。无需调用
np.empty()
并使用此
char*
cast…@ShawnWang,我发现了一种非常简单的方法,可以使用Cython数组以更干净的方式执行此操作。。。检查更新。。。