Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/148.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 通过C++;Python中的向量到numpy数组_C++_Arrays_Vector_Numpy - Fatal编程技术网

C++ 通过C++;Python中的向量到numpy数组

C++ 通过C++;Python中的向量到numpy数组,c++,arrays,vector,numpy,C++,Arrays,Vector,Numpy,我正在尝试将我在C++代码中生成的双精度向量传递给pythonnumpy数组。我希望在Python中进行一些下游处理,并希望在填充numpy数组后使用一些Python工具。我想做的最大的事情之一是能够绘制事物,C++在这方面有点笨拙。我还希望能够利用Python的统计功能 虽然我不太清楚怎么做。我花了很多时间阅读Python C API文档。我遇到了一个函数PyArray\u SimpleNewFromData,它显然可以做到这一点。至于守则的整体架构,我仍不清楚。我正在构建一些非常简单的测试用

我正在尝试将我在
C++
代码中生成的双精度向量传递给
python
numpy数组。我希望在
Python
中进行一些下游处理,并希望在填充numpy数组后使用一些Python工具。我想做的最大的事情之一是能够绘制事物,C++在这方面有点笨拙。我还希望能够利用Python的统计功能

虽然我不太清楚怎么做。我花了很多时间阅读Python C API文档。我遇到了一个函数PyArray\u SimpleNewFromData,它显然可以做到这一点。至于守则的整体架构,我仍不清楚。我正在构建一些非常简单的测试用例来帮助我理解这个过程。我在VisualStudioExpress 2012中作为一个独立的空项目生成了以下代码。我把这个文件称为Project1

#include <Python.h>
#include "C:/Python27/Lib/site-packages/numpy/core/include/numpy/arrayobject.h"

PyObject * testCreatArray()
{
    float fArray[5] = {0,1,2,3,4};
    npy_intp m = 5;
    PyObject * c = PyArray_SimpleNewFromData(1,&m,PyArray_FLOAT,fArray);
    return c; 
}
#包括
#包括“C:/Python27/Lib/site packages/numpy/core/include/numpy/arrayobject.h”
PyObject*testCreatArray()
{
浮点法拉利[5]={0,1,2,3,4};
npy_intp m=5;
PyObject*c=PyArray\u SimpleNewFromData(1,&m,PyArray\u FLOAT,fArray);
返回c;
}
我的目标是能够用Python读取PyObject。我被卡住了,因为我不知道如何在Python中引用这个模块。特别是如何从Python导入此项目,我尝试从Python中的项目路径导入Project1,但失败了。一旦我理解了这个基本情况,我的目标就是找到一种方法,将我在主函数中计算的向量容器传递给Python。我也不知道该怎么做


<任何专家谁可以帮助我,或可能张贴一个简单的包含良好的例子,一些代码读取,并填充一个麻木数组从一个简单的C++向量,我将感激不尽。非常感谢。

我在尝试做类似的事情时看到了你的帖子。我能够拼凑出一个解决方案,整个解决方案是。它将两个C++向量转换为Python元组,将它们传递给Python,将它们转换成NUMPY数组,然后使用MatPutTLB绘制它们。 这段代码大部分来自Python文档

以下是.cpp文件中的一些重要信息:

 //Make some vectors containing the data
 static const double xarr[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14};
 std::vector<double> xvec (xarr, xarr + sizeof(xarr) / sizeof(xarr[0]) );
 static const double yarr[] = {0,0,1,1,0,0,2,2,0,0,1,1,0,0};
 std::vector<double> yvec (yarr, yarr + sizeof(yarr) / sizeof(yarr[0]) );

 //Transfer the C++ vector to a python tuple
 pXVec = PyTuple_New(xvec.size()); 
 for (i = 0; i < xvec.size(); ++i) {
      pValue = PyFloat_FromDouble(xvec[i]);
      if (!pValue) {
           Py_DECREF(pXVec);
           Py_DECREF(pModule);
           fprintf(stderr, "Cannot convert array value\n");
           return 1;
      }
      PyTuple_SetItem(pXVec, i, pValue);
 }

 //Transfer the other C++ vector to a python tuple
 pYVec = PyTuple_New(yvec.size()); 
 for (i = 0; i < yvec.size(); ++i) {
      pValue = PyFloat_FromDouble(yvec[i]);
      if (!pValue) {
           Py_DECREF(pYVec);
           Py_DECREF(pModule);
           fprintf(stderr, "Cannot convert array value\n");
           return 1;
      }
      PyTuple_SetItem(pYVec, i, pValue); //
 }

 //Set the argument tuple to contain the two input tuples
 PyTuple_SetItem(pArgTuple, 0, pXVec);
 PyTuple_SetItem(pArgTuple, 1, pYVec);

 //Call the python function
 pValue = PyObject_CallObject(pFunc, pArgTuple);
这导致了我不能在这里发布的情节,因为我的声誉,但是

注意:在Numpy的扩展指南中,他们使用import\u array()来实现我使用的相同目标。当我尝试在mac上使用import_array()时,出现了一个错误。因此,您可能需要尝试这两个命令,看看哪一个命令有效

顺便说一下,您可以在调用<代码> PyRayaySimple NeFaseDAT< <代码>中使用C++ STD::vector。
如果您的std::vector是
my_vector
,请将
fArray
替换为
my_vector[0]
&my_vector[0]
允许您访问将数据存储在
my_vector

中的指针,因为对于这一问题,没有任何答案对可能正在寻找这类问题的人有实际帮助。我想我可以提出一个简单的解决方案

首先,你需要在C++中创建一个Python扩展模块,这很容易做到,而且都在Python C-API文档中,所以我不打算去做。 现在将C++ STD::vector转换成一个NUMPY数组是非常简单的。首先需要导入numpy数组头

#include <numpy/arrayobject.h>
现在,您可以使用提供的numpy数组函数。 正如几年前的OP所说,PyArray_SimpleNewFromData使用起来非常简单。您只需要一个npy_intp类型的数组,这是要创建的数组的形状。确保它与使用testVector.size()的向量相同(对于多个维度,请执行testVector[0].size()、testVector[0][0].size()等。向量在c++11中保证是连续的,除非它是布尔值)

//创建数据初始化为0的testVector
std::vector testVector;
resize(宽度,标准::向量(高度,0);
//为numpy数组创建形状
npy_intp dims[2]={宽度,高度}
//将testVector转换为numpy数组
PyArrayObject*numpyArray=(PyArrayObject*)PyArray_SimpleNewFromData(2,dims,NPY_UINT16,(UINT16_t*)testVector.data());
首先,您需要将其强制转换为PyArrayObject,否则它将是一个PyObject,并且当返回到python时将不会是一个numpy数组。 2是数组中的维数。 dims是数组的形状。它必须是npy_intp类型 NPY_UINT16是数组在python中的数据类型。 然后使用testVector.data()获取数组的数据,将其转换为void*或与向量相同数据类型的指针

希望这能帮助其他需要的人


(另外,如果您不需要纯速度,我建议您避免使用C-API,因为它会导致很多问题,cython或swig可能仍然是您的最佳选择。还有一些C类型可能会非常有用。

我不是cpp英雄,但我想为我的解决方案提供两个用于1D和2D向量的模板函数。这是一个用于使用l8ter,通过模板化1D和2D向量,编译器可以为向量形状选择正确的版本。在2D情况下,如果形状不规则,则抛出一个字符串。例程在此处复制数据,但可以轻松修改它以获取输入向量的第一个元素的地址,从而使其成为“表示”

用法如下所示:

//随机数据
vector some_vector_1D(3,1.f);//设置为1的3个条目
向量一些向量2D(3,向量(3,1.f));//3个子向量和1
//将向量转换为numpy数组
PyObject*np_vec_1D=(PyObject*)向量到数组(一些向量);
PyObject*np_vec_2D=(PyObject*)向量到数组(一些向量到数组);
您还可以通过可选参数更改numpy数组的类型
  _import_array(); //this is required for numpy to create an array correctly
#include <numpy/arrayobject.h>
PyModINIT_FUNC
inittestFunction(void){
   (void) Py_InitModule("testFunction". testFunctionMethods);
   import_array();
}
//create testVector with data initialised to 0
std::vector<std::vector<uint16_t>> testVector;
testVector.resize(width, std::vector<uint16_t>(height, 0);
//create shape for numpy array
npy_intp dims[2] = {width, height}
//convert testVector to a numpy array
PyArrayObject* numpyArray = (PyArrayObject*)PyArray_SimpleNewFromData(2, dims, NPY_UINT16, (uint16_t*)testVector.data());