【问题标题】:How do I access a numpy array in embedded python from c++?如何从 C++ 访问嵌入式 python 中的 numpy 数组?
【发布时间】:2017-04-16 13:43:41
【问题描述】:

在 C++ 中访问 2dim numpy 数组的好方法是什么?我已经查看了 numpy/c api 和其他一些帖子,但这并没有让我更进一步。情况如下:

我在一个名为 Testfile.py 的 python 文件中定义了以下 numpy 数组:

import numpy as np
A = np.array([[1, 2, 3], [1, 2, 3], [1, 2, 3]])

现在,我想在 c++ 中访问这个数组,以使用它进行进一步的计算。这是我到目前为止所做的。 注意:为简单起见,我省略了错误处理和引用计数代码 sn-ps。

#define NPY_NO_DEPRECATED_APINPY_1_7_API_VERSION
#define PY_ARRAY_UNIQUE_SYMBOL cool_ARRAY_API
#include <Python.h>
#include <arrayobject.h> // numpy!
#include <iostream>
using namespace std;
#include <stdlib.h>
#include <string>

int main(){

// Name of input-file
char pyfilename[] = "Testfile";

// initilaize python interpreter
Py_Initialize();
import_array(); 

// load input-file
PyObject *pyName = PyUnicode_FromString(pyfilename);
PyObject *pyModule = PyImport_Import(pyName);

// import my numpy array object
char pyarrayname[] = "A";
PyObject *obj = PyObject_GetAttrString(pyModule, pyarrayname);

//------------------------------------------------------------
// The Problem starts here..

// Array Dimensions
npy_intp Dims[] = { PyArray_NDIM(obj) }; // array dimension
Dims[0] = PyArray_DIM(obj, 0); // number of rows
Dims[1] = PyArray_DIM(obj, 1); // number of columns

// PyArray_SimpleNew allocates the memory needed for the array.
PyObject *ArgsArray = PyArray_SimpleNew(2, Dims, NPY_DOUBLE);

// The pointer to the array data is accessed using PyArray_DATA()
double *p = (double *)PyArray_DATA(ArgsArray);

for (int i = 0; i<Dims[0]; i++)
{
    for (int j = 0; j<Dims[1]; j++)
        {
             p[i * Dims[1] + j] = *((int *)PyArray_GETPTR2(obj, i, j));
        }
}
// -----------------------------------------------------------


Py_Finalize();

return 0;
}

我使用 python 3.6 和 MSVC 2015。

编辑:我添加了我使用的标题并稍微改变了问题的表述。

编辑:我添加了 SwiftAlan Stokes

提供的建议解决方案策略

【问题讨论】:

  • 调用数组是什么意思?
  • 对我来说,这意味着使用之前定义的数据。例如,首先我定义一个整数 int a=1;稍后,我在代码的其他地方使用/调用这个变量,例如诠释 b; b=a+1;我不确定“呼叫”这个词是否正确:P
  • 在我的例子中,我使用 numpy 在 python 中定义了一个名为 A 的数组。现在我想在我的 c++ 代码中使用/调用这个数组来将它用于其他一些微积分。 :)
  • “呼叫”通常不是这个意思;你调用一个函数,但你访问一个变量或数组元素。数组在通常意义上是不可调用的。 PyArray_GETPTR2 可能会对您有所帮助。
  • @Alan Stokes 啊,这听起来像是 LUA 和 Python 的细节……因为它们使用调用(即括号)来访问所有内容

标签: python c++ arrays numpy c-api


【解决方案1】:

通过

访问数组后
double *p = (double*)PyArray_DATA(ArgsArray);
int* pA = (int*)PyArray_DATA(obj);

您可以像使用数组一样使用它。什么是维度?

int height = PyArray_DIM(obj, 0);
int width = PyArray_DIM(obj, 1);

现在您可以使用该指针访问数组中的数据

for ( int i = 0; y<height; y++) 
{ 
   for (int j = 0; x<width; x++) 
   { 
      p[i * width + j] = pA[i * width + j];
   }
}

其实如果只需要复制数组,此时使用memcpy或者std::copy即可。

Tbh,我曾考虑使用 boost.python,但这是我自己的偏好。

【讨论】:

  • 不使用pA[i * width + j],有没有办法拥有一个多维数组?例如。像pA[i][j]一样访问它?
  • @decadenza 通过编写一些带有操作符的包装器来做到这一点?在一般情况下,我不会尝试冒险回答,任何强制转换都可能导致混叠违规。我认为 boost 提供了这一点,我只是从未使用过那个扩展。
  • 非常感谢。我实际上正在研究 Python。我正在编写一些 C++ 扩展确实对大矩阵进行操作,但我发现使用一维数组非常痛苦,并且惊讶于 C++ 没有现成的东西来做这件事。另一方面,我不想添加不必要的有效负载。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-11-25
  • 1970-01-01
  • 1970-01-01
  • 2014-01-21
  • 2012-12-06
  • 2011-09-10
  • 1970-01-01
相关资源
最近更新 更多