【问题标题】:Accessing numpy array data in C (for numpy 1.7+)在 C 中访问 numpy 数组数据(对于 numpy 1.7+)
【发布时间】:2017-01-21 20:55:04
【问题描述】:

按照示例和 numpy C-API (http://docs.scipy.org/doc/numpy/reference/c-api.html),我正在尝试访问 cpp 中的 numpy 数组数据,如下所示:

#include <Python.h>
#include <frameobject.h>
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION // TOGGLE OR NOT
#include "numpy/ndarraytypes.h"
#include "numpy/arrayobject.h"
...
// here I have passed "some_python_object" to the C code
// .. and "some_python_object" has member "infobuf" that is a numpy array
//
unsigned long* fInfoBuffer;
PyObject* infobuffer = PyObject_GetAttrString(some_python_object, "infobuf");
PyObject* x_array    = PyArray_FROM_OT(infobuffer, NPY_UINT32);
fInfoBuffer          = (unsigned long*)PyArray_DATA(x_array); // DOES NOT WORK WHEN API DEPRECATION IS TOGGLED

当 API 弃用被切换时,我在编译时得到:

error: cannot convert ‘PyObject* {aka _object*}’ to ‘PyArrayObject* {aka tagPyArrayObject*}’ for argument ‘1’ to ‘void* PyArray_DATA(PyArrayObject*)’

在 numpy 1.7+ 中这样做的合法方式是什么?

【问题讨论】:

    标签: python numpy c-api


    【解决方案1】:

    您可以尝试使用更高级别的库,该库将 numpy 数组包装在具有适当容器语义的 C++ 容器中。

    试用xtensorxtensor-python 绑定。

    还有一个 cookiecutter 可以生成一个最小的 C++ 扩展项目,其中包含用于测试的所有样板、html 文档和 setup.p...

    示例:C++ 代码

    #include <numeric>                        // Standard library import for std::accumulate
    #include "pybind11/pybind11.h"            // Pybind11 import to define Python bindings
    #include "xtensor/xmath.hpp"              // xtensor import for the C++ universal functions
    #define FORCE_IMPORT_ARRAY                // numpy C api loading
    #include "xtensor-python/pyarray.hpp"     // Numpy bindings
    
    double sum_of_sines(xt::pyarray<double> &m)
    {
        auto sines = xt::sin(m);
        // sines does not actually hold any value, which are only computed upon access
        return std::accumulate(sines.begin(), sines.end(), 0.0);
    }
    
    PYBIND11_PLUGIN(xtensor_python_test)
    {
        xt::import_numpy();
        pybind11::module m("xtensor_python_test", "Test module for xtensor python bindings");
    
        m.def("sum_of_sines", sum_of_sines,
            "Computes the sum of the sines of the values of the input array");
    
        return m.ptr();
    }
    

    Python 代码:

    import numpy as np
    import xtensor_python_test as xt
    
    a = np.arange(15).reshape(3, 5)
    s = xt.sum_of_sines(v)
    s
    

    【讨论】:

    • 问题指的是C-API,答案与C++代码有关。问题仍然存在,如何使用 C-API 做到这一点。
    • 有问题的 C++ 代码使用了 C API,并将其包装在更高级别的结构中。此外,最初的问题是“我正在尝试访问 cpp 中的 numpy 数组数据”,
    【解决方案2】:

    这是因为 PyArray_DATA 需要 PyArrayObject*。 您可以尝试更改x_array的类型:

    PyArrayObject* x_array = (PyArrayObject*) PyArray_FROM_OT(infobuffer, NPY_UINT32)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-07
      • 2018-09-09
      相关资源
      最近更新 更多