简体   繁体   English

将一个 numpy 数组从 Python 传递给 C

[英]Pass a numpy array from Python to C

I'm having successfully embedded a Python script into a C module.我已成功将 Python 脚本嵌入到 C 模块中。 The Python script produces a multi-dimensional Numpy array. Python 脚本生成一个多维 Numpy 数组。 Whereas the entire calculation in python takes 9 ms, the final tolist() conversion in order to return it to C takes 4 ms alone. Python 中的整个计算需要 9 毫秒,而将其返回到 C 的最终 tolist() 转换仅需要 4 毫秒。 I would like to change that by passing the Numpy array as reference and do the iterations in C again.我想通过将 Numpy 数组作为参考传递并再次在 C 中进行迭代来改变它。 But I can't currently figure out, how this can be done.但我目前无法弄清楚,如何做到这一点。

There are a lot of samples around, which use the other way around: Passing a Numpy array to a C function which is called from Python, but this is not my use case.周围有很多示例,它们使用另一种方式:将 Numpy 数组传递给从 Python 调用的 C 函数,但这不是我的用例。

Any pointer welcome.欢迎任何指针。

Ok, it's a while ago but I solved it like so:好的,这是前一段时间,但我是这样解决的:

My python process delivers an array, containing one array, containing one array, containing N arrays of M floats each.我的python进程传递了一个数组,包含一个数组,包含一个数组,每个包含M个浮点数的N个数组。 The input is a JPEG image.输入是 JPEG 图像。

Unwrapping it like so:像这样解开它:

int predict(PyObject *pyFunction, unsigned char *image_pointer, unsigned long image_len) {

    int result = -1;

    PyObject *pImage = NULL;
    PyObject *pList = NULL;

    pImage = PyBytes_FromStringAndSize((const char *)image_pointer, image_len);
    if (!pImage) {
        fprintf(stderr, "Cannot provide image to python 'predict'\n");
        return result;
    }

    pList = PyObject_CallFunctionObjArgs(pyFunction, pImage, NULL);
    Py_DECREF(pImage);

    PyArrayObject *pPrediction = reinterpret_cast<PyArrayObject *>(pList);
    if (!pPrediction) {
        fprintf(stderr, "Cannot predict, for whatever reason\n");
        return result;
    }

    if (PyArray_NDIM(pPrediction) != 4) {
        fprintf(stderr, "Prediction failed, returned array with wrong dimensions\n");
    } else {
        RESULTPTR pResult = reinterpret_cast<RESULTPTR>(PyArray_DATA(pPrediction));

        int len0 = PyArray_SHAPE(pPrediction)[0];
        int len1 = PyArray_SHAPE(pPrediction)[1];
        int len2 = PyArray_SHAPE(pPrediction)[2];
        int len3 = PyArray_SHAPE(pPrediction)[3];

        for (int i = 0; i < len0; i++) {
            int offs1 = i * len1;
            for (int j = 0; j < len1; j++) {
                int offs2 = j * len2;
                for (int k = 0; k < len2; k++) {
                    int offs3 = k * len3;
                    for (int l = 0; l < len3; l++) {
                        float f = (*pResult)[offs1 + offs2 + offs3 + l];
                        //printf("data: %.8f\n", f);
                    }
                }
            }
        }
        result = 0;
    }
    Py_XDECREF(pList);
    return result;
}

HTH HTH

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

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