将numpy数组传递给C ++

编程入门 行业动态 更新时间:2024-10-28 13:15:38
本文介绍了将numpy数组传递给C ++的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我有一些用Python写的代码,其输出是一个numpy数组,现在我想将该输出发送到 C ++ 代码,其中将执行大部分计算.

I have some code writen in Python for which the output is a numpy array, and now I want to send that output to C++ code, where the heavy part of the calculations will be performed.

我曾尝试使用cython的 public cdef ,但是我在某些问题上运行.多谢您的协助!这是我的代码:

I have tried using cython's public cdef, but I am running on some issues. I would appreciate your help! Here goes my code:

pymodule.pyx :

from pythonmodule import result # result is my numpy array import numpy as np cimport numpy as np cimport cython @cython.boundscheck(False) @cython.wraparound(False) cdef public void cfunc(): print 'I am in here!!!' cdef np.ndarray[np.float64_t, ndim=2, mode='c'] res = result print res

一旦被cythonized,我会打电话给

Once this is cythonized, I call:

pymain.c :

#include <Python.h> #include <numpy/arrayobject.h> #include "pymodule.h" int main() { Py_Initialize(); initpymodule(); test(2); Py_Finalize(); } int test(int a) { Py_Initialize(); initpymodule(); cfunc(); return 0; }

我在 C ++ 处得到 result 变量的 NameError .我尝试使用指针定义它并从其他函数间接调用它,但是数组仍然不可见.我很确定答案很简单,但我只是不明白.感谢您的帮助!

I am getting a NameError for the result variable at C++. I have tried defining it with pointers and calling it indirectly from other functions, but the array remains invisible. I am pretty sure the answer is quite simple, but I just do not get it. Thanks for your help!

推荐答案

简短回答

NameError是由于Python找不到模块而导致的,因此工作目录不会自动添加到您的 PYTHONPATH .使用 setenv 与 C/C ++ 代码中的 setenv("PYTHONPATH",.",1); 一起解决.

Short Answer

The NameError was cause by the fact that Python couldn't find the module, the working directory isn't automatically added to your PYTHONPATH. Using setenv with setenv("PYTHONPATH", ".", 1); in your C/C++ code fixes this.

显然,有一种简单的方法可以做到这一点.使用包含已创建数组的python模块 pythonmodule.py :

There's an easy way to do this, apparently. With a python module pythonmodule.py containing an already created array:

import numpy as np result = np.arange(20, dtype=np.float).reshape((2, 10))

您可以使用 public 关键字.通过添加一些辅助功能,通常不需要触摸Python或Numpy C-API :

You can structure your pymodule.pyx to export that array by using the public keyword. By adding some auxiliary functions, you'll generally won't need to touch neither the Python, nor the Numpy C-API:

from pythonmodule import result from libc.stdlib cimport malloc import numpy as np cimport numpy as np cdef public np.ndarray getNPArray(): """ Return array from pythonmodule. """ return <np.ndarray>result cdef public int getShape(np.ndarray arr, int shape): """ Return Shape of the Array based on shape par value. """ return <int>arr.shape[1] if shape else <int>arr.shape[0] cdef public void copyData(float *** dst, np.ndarray src): """ Copy data from src numpy array to dst. """ cdef float **tmp cdef int i, j, m = src.shape[0], n=src.shape[1]; # Allocate initial pointer tmp = <float **>malloc(m * sizeof(float *)) if not tmp: raise MemoryError() # Allocate rows for j in range(m): tmp[j] = <float *>malloc(n * sizeof(float)) if not tmp[j]: raise MemoryError() # Copy numpy Array for i in range(m): for j in range(n): tmp[i][j] = src[i, j] # Assign pointer to dst dst[0] = tmp

函数 getNPArray 和 getShape 分别返回数组及其形状.添加了 copyData 以便提取 ndarray.data 并进行复制,这样您就可以完成Python的工作,而无需初始化解释器.

Function getNPArray and getShape return the array and its shape, respectively. copyData was added in order to just extract the ndarray.data and copy it so you can then finalize Python and work without having the interpreter initialized.

一个示例程序(在 C 中, C ++ 应该看起来完全相同)看起来像这样:

A sample program (in C, C++ should look identical) would look like this:

#include <Python.h> #include "numpy/arrayobject.h" #include "pyxmod.h" #include <stdio.h> void printArray(float **arr, int m, int n); void getArray(float ***arr, int * m, int * n); int main(int argc, char **argv){ // Holds data and shapes. float **data = NULL; int m, n; // Gets array and then prints it. getArray(&data, &m, &n); printArray(data, m, n); return 0; } void getArray(float ***data, int * m, int * n){ // setenv is important, makes python find // modules in working directory setenv("PYTHONPATH", ".", 1); // Initialize interpreter and module Py_Initialize(); initpyxmod(); // Use Cython functions. PyArrayObject *arr = getNPArray(); *m = getShape(arr, 0); *n = getShape(arr, 1); copyData(data, arr); if (data == NULL){ //really redundant. fprintf(stderr, "Data is NULL\n"); return ; } Py_DECREF(arr); Py_Finalize(); } void printArray(float **arr, int m, int n){ int i, j; for(i=0; i < m; i++){ for(j=0; j < n; j++) printf("%f ", arr[i][j]); printf("\n"); } }

始终记得设置:

setenv("PYTHONPATH", ".", 1);

之前,您调用 Py_Initialize ,以便Python可以在工作目录中找到模块.

before you call Py_Initialize so Python can find modules in the working directory.

其余的非常简单.它可能需要进行一些其他的错误检查,并且一定需要一个函数来释放分配的内存.

The rest is pretty straight-forward. It might need some additional error-checking and definitely needs a function to free the allocated memmory.

以您尝试的方式进行操作很麻烦,而不是值得的,使用 numpy.save 将数组保存在 npy 二进制文件中,然后使用一些 为您读取该文件的C ++库 .

Doing it the way you are attempting is way hassle than it's worth, you would probably be better off using numpy.save to save your array in a npy binary file and then use some C++ library that reads that file for you.

更多推荐

将numpy数组传递给C ++

本文发布于:2023-07-29 19:30:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1243432.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:数组   numpy

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!