View C / C ++ data as np.array from Python.
typedef struct Particle {
float x[3], v[3];
} Particle;
const int np=10;
Particle* const p= calloc(sizeof(Particle), np);
for(int i=0; i<np; ++i) {
p[i].x[0]= (float) i + 1;
}
If you want to pass this as np.array to Python, you can use the PyArray_SimpleNewFromData
function. [^ 1]
However, here I will show you how to pass only part of the data, x [3]
, to Python as an np.array. In some cases, your data structure may contain multiple types and not all in one np.array.
If the data does not exist continuously in the memory like this, but they are arranged at regular intervals, you can set strides
. [^ 2]
PyObject* PyArray_New(PyTypeObject* subtype, int nd, npy_intp* dims,
int type_num, npy_intp* strides, void* data,
int itemsize, int flags, PyObject* obj);
What is strides []
? When ʻais np.array,
strides [0]is the byte difference between ʻa [i, j]
and ʻa [i + 1, j],
strides [][1]
is the byte difference between ʻa [i, j]and ʻa [i, j + 1]
.
static PyObject* py_as_nparray(PyObject *self, PyObject *args)
{
const int nd=2;
const int ncol= 3;
npy_intp dims[]= {np, ncol};
npy_intp strides[]= {sizeof(Particle), sizeof(float)};
return PyArray_New(&PyArray_Type, nd, dims, NPY_FLOAT, strides, p->x, 0, 0, 0);
}
import numpy as np
import cext08
a = cext08.as_nparray()
[[ 1. 0. 0.]
[ 2. 0. 0.]
[ 3. 0. 0.]
[ 4. 0. 0.]
...
https://github.com/junkoda/python_c_ext/tree/master/08_nparray_stride
Recommended Posts