将数组从c传输到python
发布时间:2020-12-16 07:14:13 所属栏目:百科 来源:网络整理
导读:我正在将一个双数组从c函数传递给 python函数.我的代码是: C代码: double *compute(int size,const double a[]){ double* array; array = malloc(sizeof(double)*size); for (int i=0; isize; i++) { array[i] = 3*a[i]; } //printf("Array in compute-fun
我正在将一个双数组从c函数传递给
python函数.我的代码是:
C代码: double *compute(int size,const double a[]) { double* array; array = malloc(sizeof(double)*size); for (int i=0; i<size; i++) { array[i] = 3*a[i]; } //printf("Array in compute-function is: n["); //for(int i = 0; i < size; i++) //printf("%f,",array[i]); //printf("]n"); return array; } PYX代码: cdef class ArrayWrapper: cdef void* data_ptr cdef int size cdef set_data(self,int size,void* data_ptr): """ Set the data of the array This cannot be done in the constructor as it must recieve C-level arguments. Parameters: ----------- size: int Length of the array. data_ptr: void* Pointer to the data """ self.data_ptr = data_ptr self.size = size def __array__(self): """ Here we use the __array__ method,that is called when numpy tries to get an array from the object.""" cdef np.npy_intp shape[1] shape[0] = <np.npy_intp> self.size # Create a 1D array,of length 'size' ndarray = np.PyArray_SimpleNewFromData(1,shape,np.NPY_INT,self.data_ptr) return ndarray def __dealloc__(self): """ Frees the array. This is called by Python when all the references to the object are gone. """ free(<void*>self.data_ptr) def py_compute(int size,np.ndarray[np.double_t,ndim=1] a): """ Python binding of the 'compute' function in 'GNLSE_RHS.c' that does not copy the data allocated in C. """ cdef double *array cdef np.ndarray ndarray # Call the C function array = compute(size,<double*> a.data) array_wrapper = ArrayWrapper() array_wrapper.set_data(size,<void*> array) ndarray = np.array(array_wrapper,copy=False) # Assign our object to the 'base' of the ndarray object ndarray.base = <PyObject*> array_wrapper # Increment the reference count,as the above assignement was done in # C,and Python does not know that there is this additional reference Py_INCREF(array_wrapper) return ndarray Python代码: for i in xrange(10): x[i] = i; a = cython_wrapper.py_compute(10,x) print a 但我的结果是 [ 0 0 0 1074266112 0 1075314688 0 1075970048 0 1076363264] 而不是预期的 [ 0. 3. 6. 9. 12. 15. 18. 21. 24. 27.] 我的错误在哪里?我认为它与有问题的指针传输有关,但我不确定. 解决方法
这里的错误是在线
ndarray = np.PyArray_SimpleNewFromData(1,self.data_ptr) 你告诉numpy self.data_ptr指向一个int数组而不是一个双精度数. 您可以通过告诉numpy正确的数据类型来修复代码,如下所示: ndarray = np.PyArray_SimpleNewFromData(1,np.NPY_DOUBLE,self.data_ptr) 它应该按预期工作. 除此之外,您可以稍微简化您的包装器代码,而不必传入输入数组的大小,因为它已经包含在您传递给py_compute的np.ndarray中 def py_compute(np.ndarray[np.double_t,ndim=1] a): """ Python binding of the 'compute' function in 'GNLSE_RHS.c' that does not copy the data allocated in C. """ cdef double *array cdef np.ndarray ndarray cdef size = a.shape[0] # Call the C function array = compute(size,&a[0]) array_wrapper = ArrayWrapper() array_wrapper.set_data(size,and Python does not know that there is this additional reference Py_INCREF(array_wrapper) return ndarray (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |