扩展 Python:处理 numpy 数组

Posted

技术标签:

【中文标题】扩展 Python:处理 numpy 数组【英文标题】:Extending Python: process numpy arrays 【发布时间】:2016-07-31 17:42:23 【问题描述】:

我用 C++ 为 Python 3 编写了一个扩展

我的模块能够处理像[1.0, 0.0, 0.0] 这样的数组。 我也想添加对 numpy 数组的支持。

我使用以下代码处理数组:

PyObject * MyFunction(PyObject * self, PyObject * args) 
    PyObject * list;

    if (!PyArg_ParseTuple(args, "O!:MyFunction", PyList_Type, &list)) 
        return 0;
    

    int count = (int)PyList_Size(list);
    for (int i = 0; i < count; ++i) 
        double value = PyFloat_AsDouble(PyList_GET_ITEM(list, i));

        // ...
    

我想要一个可以迭代的函数:np.array([2,3,1,0])

TL;DR:

Numpy 等价于:

PyList_Type PyList_Size PyList_GET_ITEMPyList_GetItem

【问题讨论】:

没有真正的答案,也许你有充分的理由使用这种原生的 c++ 接口方式,但你考虑过cython。这使所有这些东西变得更容易/更好,并被一些非常酷的项目(例如 scikit-learn)使用。 通常情况正好相反:你写一个numpy函数,它也可以处理列表。 我只是不想在 C++ 中遍历一个 numpy 数组 现在我会检查cython @sascha 我不是专家,但有什么问题?如果您正在连接 C++ 代码,Cython 肯定需要一个 C++ 编译器(这对于 Windows 用户来说可能很尴尬),但同样适用于本机绑定。很多项目都使用 cython,并且可以在 PyPI 上使用。 【参考方案1】:

首先,没有numpy 等价于:

PyList_Type PyList_Size PyList_GET_ITEM 或 PyList_GetItem

numpy.array 实现了buffer interface,所以可以这样写:

const char * data;
int size;

PyArg_ParseTuple(args, "y#:MyFunction", &data, &size);

numpy.array([1.0, 0.0, 0.0]) 使用 double 精度:

double * array = (double *)data;
int length = size / sizeof(double);

完整示例:

C++

PyObject * MyFunction(PyObject * self, PyObject * args) 
    const char * data;
    int size;

    if (!PyArg_ParseTuple(args, "y#:MyFunction", &data, &size)) 
        return 0;
    

    double * content = (double *)data;
    int length = size / sizeof(double);

    for (int i = 0; i < length; ++i) 
        double value = content[i];

        // ...
    

    Py_RETURN_NONE;

Python

MyFunction(numpy.array([1.0, 2.0, 3.0]))

【讨论】:

以上是关于扩展 Python:处理 numpy 数组的主要内容,如果未能解决你的问题,请参考以下文章

初学者用 Python 扩展 C(特别是 Numpy)

Python 的 C++ 扩展模块返回一个 Numpy 数组

numpy模块

numpy模块

Python Numpy 数组扩展 repeat和tile

将 C++ 数组发送到 Python 并返回(使用 Numpy 扩展 C++)