I would like to return some data from c++ code as a numpy.array
object. I had a look at boost::python::numeric
, but its documentation is very terse
I looked at the available answers and thought, "this will be easy". I proceeded to spend hours attempting what seemed like a trivial examples/adaptations of the answers.
Then I implemented @max's answer exactly (had to install Eigen) and it worked fine, but I still had trouble adapting it. My problems were mostly (by number) silly, syntax mistakes, but additionally I was using a pointer to a copied std::vector's data after the vector seemed to be dropped off the stack.
In this example, a pointer to the std::vector is returned, but also you could return the size and data() pointer or use any other implementation that gives your numpy array access to the underlying data in a stable manner (i.e. guaranteed to exist):
class_("test_wrap")
.add_property("values", +[](test_wrap& self) -> object {
return wrap(self.pvalues()->data(),self.pvalues()->size());
})
;
For test_wrap with a std::vector
(normally pvalues() might just return the pointer without populating the vector):
class test_wrap {
public:
std::vector mValues;
std::vector* pvalues() {
mValues.clear();
for(double d_ = 0.0; d_ < 4; d_+=0.3)
{
mValues.push_back(d_);
}
return &mValues;
}
};
The full example is on Github so you can skip the tedious transcription steps and worry less about build, libs, etc. You should be able to just do the following and get a functioning example (if you have the necessary features installed and your path setup already):
git clone https://github.com/ransage/boost_numpy_example.git
cd boost_numpy_example
# Install virtualenv, numpy if necessary; update path (see below*)
cd build && cmake .. && make && ./test_np.py
This should give the output:
# cmake/make output
values has type
values has len 14
values is [ 0. 0.3 0.6 0.9 1.2 1.5 1.8 2.1 2.4 2.7 3. 3.3 3.6 3.9]
*In my case, I put numpy into a virtualenv as follows - this should be unnecessary if you can execute python -c "import numpy; print numpy.get_include()"
as suggested by @max:
# virtualenv, pip, path unnecessary if your Python has numpy
virtualenv venv
./venv/bin/pip install -r requirements.txt
export PATH="$(pwd)/venv/bin:$PATH"
Have fun! :-)