Dombi Szabolcs Dombi Szabolcs - 2 months ago 19
C++ Question

Extending Python: process numpy arrays

I wrote an extension for Python 3 in C++

My module is capable of handling arrays like

[1.0, 0.0, 0.0]
.
I want to add support for numpy arrays as well.

I process arrays with the following code:

PyObject * MyFunction(PyObject * self, PyObject * args) {
PyObject * list;

if (!PyArg_ParseTuple(args, "O!:MyFunction", PyList_Type, &list)) {
return 0;
}

int count = (int)PyList_Size(list);
for (int i = 0; i < count; ++i) {
double value = PyFloat_AsDouble(PyList_GET_ITEM(list, i));

// ...
}
}


I want a function that can iterate through this:
np.array([2,3,1,0])


TL;DR:

Numpy equivalent for:


  • PyList_Type

  • PyList_Size

  • PyList_GET_ITEM
    or
    PyList_GetItem


Answer

First of all there is no numpy equivalent for:

  • PyList_Type
  • PyList_Size
  • PyList_GET_ITEM or PyList_GetItem

The numpy.array implements the buffer interface, so one can write:

const char * data;
int size;

PyArg_ParseTuple(args, "y#:MyFunction", &data, &size);

The numpy.array([1.0, 0.0, 0.0]) uses double precision:

double * array = (double *)data;
int length = size / sizeof(double);

The full example:

  • C++

    PyObject * MyFunction(PyObject * self, PyObject * args) {
        const char * data;
        int size;
    
        if (!PyArg_ParseTuple(args, "y#:MyFunction", &data, &size)) {
            return 0;
        }
    
        double * content = (double *)data;
        int length = size / sizeof(double);
    
        for (int i = 0; i < length; ++i) {
            double value = content[i];
    
            // ...
        }
    
        Py_RETURN_NONE;
    }
    
  • Python

    MyFunction(numpy.array([1.0, 2.0, 3.0]))
    
Comments