简体   繁体   English

将PyArrayObject数据类型转换为C数组

[英]typecasting PyArrayObject data to a C array

I want to work with my Numpy arrays in a C extension. 我想在C扩展中使用我的Numpy数组。 Many examples in this case uses the structure of PyArrayObject, 在这种情况下,许多示例使用PyArrayObject的结构,

array->data , array->strides[0] , array->strides[1] , ...

pointers in order to reach the data, if I wanted to reach my array in a more familiar (or tidier) way to me, with indices like 如果我想以更熟悉(或更整洁)的方式到达我的数组,以及像

array[i][j]

how should I proceed so? 我该怎么办呢? Should I typecast (bool *) array->data and work with the C array I created? 我应该使用类型转换(bool *)array-> data并使用我创建的C数组吗? (my elements are bools) (我的元素是bools)

My function declaration for now is (not finished, of course) 我现在的功能声明是(当然没有完成)

static PyObject *
xor_masking(PyObject *self, PyObject *args)
{

PyObject *input;
PyObject *mask;
PyObject *adjacency;
PyObject *state;
PyArrayObject *arr_mask;
PyArrayObject *arr_adjacency;
PyArrayObject *arr_state;
PyArrayObject *arr_next_state;

double sum;
int counter_node, n_nodes;

/*  PyArg_ParseTuple
 *  checks if from args, the pointers of type "O" can be extracted, and extracts them
 */

if (!PyArg_ParseTuple(args, "OOO:xor_masking_C", &mask, &adjacency, &state))
    return NULL;

/*
 *  The pointer returned by PyArray_ContiguousFromObject is typecasted to
 *  a PyArrayObject Pointer and array is pointed to the same address.
 */

arr_mask = (PyArrayObject *)
PyArray_ContiguousFromObject(mask, PyArray_BOOL, 2, 2);
arr_adjacency = (PyArrayObject *)
PyArray_ContiguousFromObject(adjacency, PyArray_BOOL, 2, 2);
arr_state = (PyArrayObject *)
PyArray_ContiguousFromObject(state, PyArray_BOOL, 2, 2);

if (array == NULL)
    return NULL;

int n_mask_0 = mask->dimensions[0];
int n_mask_1 = mask->dimensions[1];
int n_adjacency_0 = adjacency->dimensions[0];
int n_adjacency_1 = adjacency->dimensions[1];
int n_state_0 = state->dimensions[0];
int n_nodes = n_state_0;
/*
 * if the dimensions don't match, return NULL
 */

bool c_mask[n_nodes][n_nodes];

if (n_mask_0 != n_mask_1 || n_adjacency_0 != n_adjacency_1 ||
n_adjacency_0 != n_mask_0 || n_adjacency_0 != n_adjacency_1) {
    return NULL;
}

/*
 *    The 2D arrays are introduced as follows
 *    array[i][j] = (array->data + i*array->strides[0] + j*array->strides[1])
 */

for (counter_node = 0; i < n_mask; i++){
    *row_start = (array->data + i*array->strides[0]);
}


//Py_DECREF();

//return PyFloat_FromDouble();
}

Thanks! 谢谢!

I'm not sure if this answers your question but, to reach your NumPy data in C, you could try to create an iterator to loop over your array in C. It doesn't give you indexing you're after ([i][j]) but it covers the entire array 我不确定这是否能回答你的问题但是,为了在C中获取你的NumPy数据,你可以尝试创建一个迭代器来循环你的数组。它没有给你索引你在之后([i] [j])但它涵盖整个阵列

static PyObject *func1(PyObject *self, PyObject *args) {
    PyArrayObject *X;
    int ndX;
    npy_intp *shapeX;
    NpyIter *iter;
    NpyIter_IterNextFunc *iternext;
    PyArray_Descr *dtype;
    double **dataptr;

    PyArg_ParseTuple(args, "O!", &PyArray_Type, &X);
    ndX = PyArray_NDIM(X);
    shapeX = PyArray_SHAPE(X);
    dtype = PyArray_DescrFromType(NPY_DOUBLE);
    iter = NpyIter_New(X, NPY_ITER_READONLY, NPY_KEEPORDER, NPY_NO_CASTING, dtype);
    iternext = NpyIter_GetIterNext(iter, NULL);
    dataptr = (double **) NpyIter_GetDataPtrArray(iter);
    do {
        cout << **dataptr << endl; //Do something with the data in your array
    } while (iternext(iter));   
    NpyIter_Deallocate(iter);
    return Py_BuildValue(...);
}

I think you'll want to look at this: http://docs.scipy.org/doc/numpy/reference/c-api.array.html 我想你会想看看这个: http//docs.scipy.org/doc/numpy/reference/c-api.array.html

In particular, 特别是,

void* PyArray_GETPTR3(PyObject* obj, <npy_intp> i, <npy_intp> j, <npy_intp> k)

and friends. 和朋友。 Those are the functions that David Heffernan would be surprised if the API didn't provide. 如果API没有提供,David Heffernan会感到惊讶的是这些功能。

This is the dirtiest of all answers here, I guess, but 2 years ago, I ended up implementing this function like this: 这是所有答案中最脏的,我猜,但是2年前,我最终实现了这样的功能:

Just adding it here for documenting it. 只需在此处添加它以记录它。 If you are reading this, you should check out other solutions, which are better. 如果您正在阅读本文,则应查看其他更好的解决方案。

https://gist.github.com/mehmetalianil/6643299 https://gist.github.com/mehmetalianil/6643299

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM