0

What would be a good way to access a 2dim numpy array in c++? I've already checked out the numpy/c api and some other posts but that doesn't brought me further. Here's the situation:

I defined in a python file called Testfile.py the following numpy array:

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

Now, I would like to access this array in c++ to use it for further calculations. Here is what i did so far. Note: For simplicity, i left out error handling and reference counting code snippets.

#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;
}

I use python 3.6 and MSVC 2015.

EDIT: I added the headers i use and changed the problem formulation a bit.

EDIT: I added the proposed solution strategies provided by Swift and Alan Stokes

15
  • What does it mean to call an array? Commented Apr 16, 2017 at 13:52
  • For me it means, to use previously defined data. For example, first i define an integer int a=1; later on, i use/call this variable somewhere else in the code e.g. int b; b=a+1; I'm not sure if the word "call" is the right term :P Commented Apr 16, 2017 at 14:22
  • In my case, i define a array called A in python, using numpy. Now i would like to use/call this array inside my c++ code to use it for some other calculus. :) Commented Apr 16, 2017 at 14:24
  • That's not what "call" normally means; you call a function, but you access a variable or array element. An array is not callable in the usual sense. PyArray_GETPTR2 might help you. Commented Apr 16, 2017 at 14:27
  • @Alan Stokes ah, that sounds like LUA and Python specifics.. as they use calling (that is, parenthesis) to access everything Commented Apr 16, 2017 at 14:58

1 Answer 1

1

After you access array by

double *p = (double*)PyArray_DATA(ArgsArray);
int* pA = (int*)PyArray_DATA(obj);

you can work with it like with array. What are dimensions?

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

Now you can use that pointer to access data in array

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

Actually, if you just need to copy array, use memcpy or std::copy at this point.

Tbh, I'd considered to use boost.python instead, but it's my own preference.

Sign up to request clarification or add additional context in comments.

3 Comments

Instead of using pA[i * width + j], is there a way to have a multi-dimensional array? E.g. accessing it like pA[i][j]?
@decadenza by writing some wrapper with operators that do that? I won't try and risk answer in general case, any casts can lead to aliasing breach. I think boost offers that, I just never used that extension.
Many thanks. I am actually working on Python. I am writing some C++ extensions do do operations on big matrices but I found extremely painful to work with one dimensional arrays and surprised that C++ has got nothing off the shelf to do this. On the other side I do not want to add unnecessary payload.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.