Accessing view of a NumPy array using the C API Accessing view of a NumPy array using the C API numpy numpy

Accessing view of a NumPy array using the C API


The view of the array is just another information-wrapper for the same data array. Numpy doesn't copy any data here. Only the information for the interpretation of the data are adjusted and the pointer to the data moved if useful.

In your code you're assuming, that the data of a vector a[:, 3] is represented as a vector in memory which wouldn't differ for NPY_ARRAY_CARRAY and NPY_ARRAY_FARRAY. But this representation you only get after creating a (fortran ordered) copy of the array itself.

To make it work I modified your convertPyArrayToArma() function a little to create a copy even if it's a vector:

template<typename outT>static arma::Mat<outT> convertPyArrayToArma(PyArrayObject* pyarr, int nrows, int ncols){    if (!checkPyArrayDimensions(pyarr, nrows, ncols)) throw WrongDimensions();    int arrTypeCode;    if (std::is_same<outT, uint16_t>::value) {        arrTypeCode = NPY_UINT16;    }    else if (std::is_same<outT, double>::value) {        arrTypeCode = NPY_DOUBLE;    }    else {        throw NotImplemented();    }    PyArray_Descr* reqDescr = PyArray_DescrFromType(arrTypeCode);    if (reqDescr == NULL) throw std::bad_alloc();    PyArrayObject* cleanArr = (PyArrayObject*)PyArray_FromArray(pyarr, reqDescr, NPY_ARRAY_FARRAY);    if (cleanArr == NULL) throw std::bad_alloc();    reqDescr = NULL;  // The new reference from DescrFromType was stolen by FromArray    const auto dims = getPyArrayDimensions(pyarr);    outT* dataPtr = static_cast<outT*>(PyArray_DATA(cleanArr));    // this copies the data from cleanArr    arma::Mat<outT> result;    if (dims.size() == 1) {        result = arma::Col<outT>(dataPtr, dims[0], true);    }    else {        result = arma::Mat<outT>(dataPtr, dims[0], dims[1], true);    }    Py_DECREF(cleanArr);    return result;}