gpt4 book ai didi

python - 将数组从 c 传输到 python

转载 作者:太空狗 更新时间:2023-10-29 15:40:21 25 4
gpt4 key购买 nike

我正在将 double 数组从 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, shape,
np.NPY_INT, self.data_ptr)

你告诉 numpy self.data_ptr指向一个整数数组,不是 double 组。

您可以像这样告诉 numpy 正确的数据类型来修复您的代码:

ndarray = np.PyArray_SimpleNewFromData(1, shape,
np.NPY_DOUBLE, self.data_ptr)

它应该按预期工作。

除此之外,您还可以通过不必传入输入数组的大小来稍微简化包装器代码,因为它已包含在 np.ndarray 中。你传递给py_compute

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, <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 - 将数组从 c 传输到 python,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33608313/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com