Passing a C++ std::Vector to numpy array in Python

前端 未结 4 695
走了就别回头了
走了就别回头了 2021-02-04 06:13

I am trying a pass a vector of doubles that I generate in my C++ code to a python numpy array. I am looking to do some downstream processing in P

4条回答
  •  太阳男子
    2021-02-04 06:41

    Since there is no answer to this that is actually helpful for people that might be looking for this sort of thing I figured I'd put an easy solution.

    First you will need to create a python extension module in C++, this is easy enough to do and is all in the python c-api documentation so i'm not going to go into that.

    Now to convert a c++ std::vector to a numpy array is extremely simple. You first need to import the numpy array header

    #include 
    

    and in your intialising function you need to import_array()

    PyModINIT_FUNC
    inittestFunction(void){
       (void) Py_InitModule("testFunction". testFunctionMethods);
       import_array();
    }
    

    now you can use the numpy array functions that are provided. The one that you will want for this is as the OP said a few years back PyArray_SimpleNewFromData, it's stupidly simple to use. All you need is an array of type npy_intp, this is the shape of the array to be created. make sure it is the same as your vector using testVector.size(), (and for multiple dimensions do testVector[0].size(), testVector[0][0].size() ect. vectors are guaranteed to be continuous in c++11 unless it's a bool).

    //create testVector with data initialised to 0
    std::vector> testVector;
    testVector.resize(width, std::vector(height, 0);
    //create shape for numpy array
    npy_intp dims[2] = {width, height}
    //convert testVector to a numpy array
    PyArrayObject* numpyArray = (PyArrayObject*)PyArray_SimpleNewFromData(2, dims, NPY_UINT16, (uint16_t*)testVector.data());
    

    To go through the paramaters. First you need to cast it to a PyArrayObject, otherwise it will be a PyObject and when returned to python won't be a numpy array. The 2, is the number of dimensions in the array. dims, is the shape of the array. This has to be of type npy_intp NPY_UINT16 is the data type that the array will be in python. you then use testVector.data() to get the data of the array, cast this to either void* or a pointer of the same data type as your vector.

    Hope this helps anyone else who may need this.

    (Also if you don't need pure speed I would advise avoiding using the C-API, it causes quite a few problems and cython or swig are still probably your best choices. There is also c types which can be quite helpful.

提交回复
热议问题