【问题标题】:cython: convert float array to python array with numpy.ctypeslib.ndpointercython:使用 numpy.ctypeslib.ndpointer 将浮点数组转换为 python 数组
【发布时间】:2015-10-13 13:34:59
【问题描述】:

我想在 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)

【问题讨论】:

  • 虽然您的问题与stackoverflow.com/questions/23872946/… 不同,但我认为答案将是您想要的。
  • 我认为 ctypes 不是正确的方法(无论如何你误解了ndpointer,它用于声明函数接口)。
  • 您也可以查看docs.cython.org/src/userguide/memoryviews.html#cython-arrays 以了解解决同一问题的不同方法,但如果您想要一个 numpy 数组,您可能会发现第一个链接更有帮助。
  • 如果这是您的主要要求,我认为 cython 数组/memoryview 方法(在我的第三条评论中)可能是最简单的选择。
  • 好。两件事:1)回答你自己的问题比将答案编辑到问题中更有用。 2)想想内存是如何被释放的?我不认为它在你那里的非常简单的版本中......

标签: python c arrays numpy cython


【解决方案1】:

@DavidW 指出numpy.ctypeslib.ndpointer 不是我想做的事情的正确方式。

基本上我只想将c-array 转换为cython/python-array

借助此链接,我找到了答案: http://docs.cython.org/src/userguide/memoryviews.html#cython-arrays

def py_compute(int size):
    return <float[:size]> (compute(size))

我在 c 中释放内存,这样我就不必担心在 python 中释放它,因此可以使用这个非常简单的解决方案。

【讨论】:

    猜你喜欢
    • 2012-07-26
    • 2013-08-19
    • 2021-12-12
    • 1970-01-01
    • 1970-01-01
    • 2021-12-28
    • 1970-01-01
    • 2019-07-05
    • 1970-01-01
    相关资源
    最近更新 更多