how to return numpy.array from boost::python?

后端 未结 5 2113
有刺的猬
有刺的猬 2020-11-28 08:03

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

5条回答
  •  春和景丽
    2020-11-28 08:37

    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! :-)

提交回复
热议问题