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
. I am using Boost.Python with its NumPy extension. My problem specifically lies in converting from ndarray
to vector
, as I am using an extended class of 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
x2
and filled with x,y data. Then I process the data in C++ with a function, which returns an std::vector<Vector>
. This vector then should be returned to Python as an ndarray
, BUT only with the x and y values.
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.
#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:
boost::python::numpy::ndarray
to a std::vector<Vector>
?std::vector<Vector>
to an boost::python::numpy::ndarray
, returning only x and y?As a last note: I know almost nothing about Python, and I am beginner/moderate in C++.
To convert a one-dimensional NumPy array to a list use tolist() function of the ndarray, First, let's create a ndarray using array() function and then use tolist() function to convert it to a list. The array() function takes a Python list as an argument.
numpy. array is just a convenience function to create an ndarray ; it is not a class itself. You can also create an array using numpy. ndarray , but it is not the recommended way.
To save the Numpy array as a local image, use the save() function and pass the image filename with the directory where to save it. This will save the Numpy array as a jpeg image.
The array object in NumPy is called ndarray . We can create a NumPy ndarray object by using the array() function.
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
:
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
:
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:
np::ndarray output_array = output.copy();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With