简体   繁体   English

如何使用Boost.Python将NumPy ndarray转换为C ++向量并返回?

[英]How to convert NumPy ndarray to C++ vector with Boost.Python and back?

I am working on a project where I need to convert an ndarray in Python to a vector in C++ and then return a processed vector from C++ back to Python in an ndarray . 我正在开发一个项目,我需要将Python中的ndarray转换为C ++中的vector ,然后在ndarray处理后的vector从C ++返回到Python。 I am using Boost.Python with its NumPy extension . 我正在使用Boost.Python及其NumPy扩展 My problem specifically lies in converting from ndarray to vector , as I am using an extended class of vector: 我的问题特别在于从ndarray转换为vector ,因为我正在使用扩展的vector类:

class Vector
{
   public:
      Vector();
      Vector(double x, double y, double z);
      /* ... */
      double GetLength(); // Return this objects length.
      /* ... */
      double x, y, z;
};

The ndarray I receive is n x 2 and filled with x,y data. 我收到的ndarrayn x 2并填充x,y数据。 Then I process the data in C++ with a function, which returns an std::vector<Vector> . 然后我用一个函数处理C ++中的数据,该函数返回一个std::vector<Vector> This vector then should be returned to Python as an ndarray , BUT only with the x and y values. 然后应该将此向量作为ndarray返回到Python,但仅限于x和y值。

I have written the following piece of code, with inspiration from " how to return numpy.array from boost::python? " and the gaussian.cpp from the Boost NumPy examples. 我编写了下面这段代码,灵感来自“ 如何从boost :: python返回numpy.array? ”和Boost NumPy示例中的gaussian.cpp

#include <vector>
#include "Vector.h"
#include "ClothoidSpline.h"

#include <boost/python/numpy.hpp>

namespace py = boost::python;
namespace np = boost::python::numpy;

std::vector<Vector> getFineSamples(std::vector<Vector> data)
{
    /* ... */
}

np::ndarray wrapper(np::ndarray const & input)
{
    std::vector<Vector> data;

    /* Python ndarray --> C++ Vector */
    Py_intptr_t const* size = input.get_shape();
    Py_intptr_t const* strides = input.get_strides();

    double x;
    double y;
    double z = 0.0;

    for (int i = 0; i < size[0]; i++)
    {
        x = *reinterpret_cast<double const *>(input.get_data() + i * strides[0] + 0 * strides[1]);
        y = *reinterpret_cast<double const *>(input.get_data() + i * strides[0] + 1 * strides[1]);
        data.push_back(Vector::Vector(x,y,z));
    }

    /* Run Algorithm */
    std::vector<Vector> v = getFineSamples(data);

    /* C++ Vector --> Python ndarray */
    Py_intptr_t shape[1] = { v.size() };
    np::ndarray result = np::zeros(2, shape, np::dtype::get_builtin<std::vector<Vector>>());
    std::copy(v.begin(), v.end(), reinterpret_cast<double*>(result.get_data()));

    return result;
}

EDIT: I am aware that this is a (possibly) failed attempt, and I am more interested in a better method to solve this problem, than edits to my code. 编辑:我知道这是一个(可能)失败的尝试,我更感兴趣的是一个更好的方法来解决这个问题,而不是编辑我的代码。

So to sum up : 总结一下

  1. How do I convert an boost::python::numpy::ndarray to a std::vector<Vector> ? 如何将boost::python::numpy::ndarray转换为std::vector<Vector>
  2. How do I convert a std::vector<Vector> to an boost::python::numpy::ndarray , returning only x and y? 如何将std::vector<Vector>转换为boost::python::numpy::ndarray ,仅返回x和y?

As a last note : I know almost nothing about Python, and I am beginner/moderate in C++. 作为最后一点 :我对Python几乎一无所知,而且我在C ++中是初学/中等。

I will consider the title of your question to give a more generalized answer to whoever finds this post. 我将考虑你的问题的标题,以便对发现这篇文章的人给出更广泛的答案。

You have a boost::python::numpy::ndarray called input that contains doubles and you want to convert it a std::vector<double> called v : 你有一个boost::python::numpy::ndarray叫做input ,它包含doubles ,你想把它转换成一个名为vstd::vector<double>

int input_size = input.shape(0);
double* input_ptr = reinterpret_cast<double*>(input.get_data());
std::vector<double> v(input_size);
for (int i = 0; i < input_size; ++i)
    v[i] = *(input_ptr + i);

Now, you have a std::vector<double> called v and you want to convert it back to boost::python::numpy::ndarray of doubles called output : 现在,你有一个名为vstd::vector<double> ,你想将它转换回boost::python::numpy::ndarray of doubles名为output

int v_size = v.size();
py::tuple shape = py::make_tuple(v_size);
py::tuple stride = py::make_tuple(sizeof(double));
np::dtype dt = np::dtype::get_builtin<double>();
np::ndarray output = np::from_data(&v[0], dt, shape, stride, py::object());

Supposing you are wrapping this function, don't forget that you need to create a new reference to this array before returning it to python: 假设您正在包装此函数,请不要忘记在将其返回到python之前需要创建对此数组的新引用:

np::ndarray output_array = output.copy();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM