cython:使用 numpy.ctypeslib.ndpointer 将浮点数组转换为 python 数组
cython: convert float array to python array with numpy.ctypeslib.ndpointer
我想在 cython/python 代码中使用来自 c 数组的数据。
为此,我尝试将 c 数组转换为 numpy.ctypeslib.ndpointer
。
我收到错误 Cannot convert 'float *' to Python object
。
下面是一个简单的例子,我已经尝试起床 运行 几天了。
假设我们有一个创建数组的 c 函数。 c_code.c
float *compute(int size)
{
float* array;
array = malloc(sizeof(float)*size);
int i;
for (i=0; i<size; i++)
{
array[i] = i;
}
return array;
}
在 cython 中我有 cython_wrapper.pyx
:
# Declare the prototype of the C function we are interested in calling
cdef extern from "c_code.c":
float*compute(int size)
# Import the Python-level symbols of numpy
import numpy as np
# Import the C-level symbols of numpy
cimport numpy as np
import ctypes
# Numpy must be initialized. When using numpy from C or Cython you must
# _always_ do that, or you will have segfaults
np.import_array()
def py_compute(int size):
""" Python binding of the 'compute' function in 'c_code.c' that does
not copy the data allocated in C.
"""
cdef float *array
cdef np.ndarray ndarray
# Call the C function
array = compute(size)
func = np.ctypeslib.ndpointer(dtype=ctypes.c_int, shape=(size,))
ndarray = func(array)
return ndarray
setup.py
:
import numpy
from Cython.Distutils import build_ext
def configuration(parent_package='', top_path=None):
""" Function used to build our configuration.
"""
from numpy.distutils.misc_util import Configuration
# The configuration object that hold information on all the files
# to be built.
config = Configuration('', parent_package, top_path)
config.add_extension('cython_wrapper',
sources=['cython_wrapper.pyx'],
# libraries=['m'],
depends=['c_code.c'],
include_dirs=[numpy.get_include()])
return config
if __name__ == '__main__':
# Retrieve the parameters of our local configuration
params = configuration(top_path='').todict()
# Override the C-extension building so that it knows about '.pyx'
# Cython files
params['cmdclass'] = dict(build_ext=build_ext)
# Call the actual building/packaging function (see distutils docs)
from numpy.distutils.core import setup
setup(**params)
@DavidW 指出 numpy.ctypeslib.ndpointer
不是我想做的事情的正确方法。
基本上我只想将 c-array
转换为 cython/python-array
。
借助这个 link 我找到了答案:
http://docs.cython.org/src/userguide/memoryviews.html#cython-arrays
def py_compute(int size):
return <float[:size]> (compute(size))
我正在释放 c 中的内存,这样我就不必担心在 python 中释放它,因此可以使用这个非常简单的解决方案。
我想在 cython/python 代码中使用来自 c 数组的数据。
为此,我尝试将 c 数组转换为 numpy.ctypeslib.ndpointer
。
我收到错误 Cannot convert 'float *' to Python object
。
下面是一个简单的例子,我已经尝试起床 运行 几天了。
假设我们有一个创建数组的 c 函数。 c_code.c
float *compute(int size)
{
float* array;
array = malloc(sizeof(float)*size);
int i;
for (i=0; i<size; i++)
{
array[i] = i;
}
return array;
}
在 cython 中我有 cython_wrapper.pyx
:
# Declare the prototype of the C function we are interested in calling
cdef extern from "c_code.c":
float*compute(int size)
# Import the Python-level symbols of numpy
import numpy as np
# Import the C-level symbols of numpy
cimport numpy as np
import ctypes
# Numpy must be initialized. When using numpy from C or Cython you must
# _always_ do that, or you will have segfaults
np.import_array()
def py_compute(int size):
""" Python binding of the 'compute' function in 'c_code.c' that does
not copy the data allocated in C.
"""
cdef float *array
cdef np.ndarray ndarray
# Call the C function
array = compute(size)
func = np.ctypeslib.ndpointer(dtype=ctypes.c_int, shape=(size,))
ndarray = func(array)
return ndarray
setup.py
:
import numpy
from Cython.Distutils import build_ext
def configuration(parent_package='', top_path=None):
""" Function used to build our configuration.
"""
from numpy.distutils.misc_util import Configuration
# The configuration object that hold information on all the files
# to be built.
config = Configuration('', parent_package, top_path)
config.add_extension('cython_wrapper',
sources=['cython_wrapper.pyx'],
# libraries=['m'],
depends=['c_code.c'],
include_dirs=[numpy.get_include()])
return config
if __name__ == '__main__':
# Retrieve the parameters of our local configuration
params = configuration(top_path='').todict()
# Override the C-extension building so that it knows about '.pyx'
# Cython files
params['cmdclass'] = dict(build_ext=build_ext)
# Call the actual building/packaging function (see distutils docs)
from numpy.distutils.core import setup
setup(**params)
@DavidW 指出 numpy.ctypeslib.ndpointer
不是我想做的事情的正确方法。
基本上我只想将 c-array
转换为 cython/python-array
。
借助这个 link 我找到了答案: http://docs.cython.org/src/userguide/memoryviews.html#cython-arrays
def py_compute(int size):
return <float[:size]> (compute(size))
我正在释放 c 中的内存,这样我就不必担心在 python 中释放它,因此可以使用这个非常简单的解决方案。