массив numpy C api

У меня есть функция C ++, возвращающая std :: vector, и я хочу использовать ее в python, поэтому я использую C numpy api:

static PyObject * py_integrate(PyObject *self, PyObject *args){ ... std::vector<double> integral; cpp_function(integral); // This changes integral npy_intp size = {integral.size()}; PyObject *out = PyArray_SimpleNewFromData(1, &size, NPY_DOUBLE, &(integral[0])); return out; } 

Вот как я называю это из python:

 import matplotlib.pyplot as plt a = py_integrate(parameters) print a fig = plt.figure() ax = fig.add_subplot(111) ax.plot(a) print a 

Что происходит: первая печать в порядке, значения правильные. Но когда я замышляю, что это не так; во второй печати я вижу очень странные значения, такие как 1E-308 1E-308 ... или 0 0 0 ... как неинициализированная память. Я не понимаю, почему первая печать в порядке.

Частичное решение (не работает):

 static void DeleteVector(void *ptr) { std::cout << "Delete" << std::endl; vector * v = static_cast<std::vector<double> * >(ptr); delete v; return; } static PyObject * cppfunction(PyObject *self, PyObject *args) { std::vector<double> *vector = new std::vector<double>(); vector->push_back(1.); PyObject *py_integral = PyCObject_FromVoidPtr(vector, DeleteVector); npy_intp size = {vector->size()}; PyArrayObject *out; ((PyArrayObject*) out)->base = py_integral; return (PyObject*)(out); } 

2 Solutions collect form web for “массив numpy C api”

Ваш std::vector объект кажется локальным для этой функции. PyArray_SimpleNewFromData не делает копию данных, которые вы передаете. Он просто держит указатель. Итак, как только ваша функция py_integrate вернется, вектор будет освобожден. Печать работает в первый раз, потому что ничего еще не написано над освобожденной памятью, но к тому времени, как вы дошли до следующей печати, что-то еще использовало эту память, в результате чего значения были разными.

Вам нужно создать массив NumPy, которому принадлежит собственное пространство для хранения, а затем скопировать данные в него.

Альтернативно, выделите свой вектор в куче. Затем сохраните указатель на него в CObject . Предоставьте деструктор, который удаляет вектор. Затем взгляните на тип PyArrayObject на уровне C. Он имеет член PyObject * называемый base . Сохраните свой CObject . Затем, когда массив NumPy будет собран мусором, счетчик ссылок на этом базовом объекте будет уменьшен, и, предположив, что вы не взяли его копию в другом месте, ваш вектор будет удален благодаря деструктору, который вы предоставили.

Fixer-верхний

Вы забыли создать PyArray. Попробуй это:

(Вы не опубликовали DeleteVector , так что я могу только надеяться, что это правильно)

 std::vector<double> *vector = new std::vector<double>(); vector->push_back(1.); PyObject *py_integral = PyCObject_FromVoidPtr(vector, DeleteVector); npy_intp size = {vector->size()}; PyObject *out = PyArray_SimpleNewFromData(1, &size, NPY_DOUBLE, &((*vector)[0])); ((PyArrayObject*) out)->base = py_integral; return out; 

Примечание. Я не программист на C ++, поэтому могу только предположить, что &((*vector)[0]) работает по назначению с указателем на вектор. Я знаю, что вектор перераспределяет область хранения, если вы его вырасти, поэтому не увеличивайте его размер после получения этого указателя, или он больше не будет действителен.

Вам нужно будет сделать копию вектора, так как вектор выйдет за пределы области действия, и память больше не будет использоваться к моменту, когда вам это понадобится в Python (как указано в kwatford).

Один из способов сделать массив Numpy вам необходим (путем копирования данных):

 PyObject *out = nullptr; std::vector<double> *vector = new std::vector<double>(); vector->push_back(1.); npy_intp size = {vector.size()}; out = PyArray_SimpleNew(1, &size, NPY_DOUBLE); memcpy(PyArray_DATA((PyArrayObject *) out), vector.data(), vector.size()); 
Interesting Posts

Python (или общее программирование). Зачем использовать <> вместо! = И есть ли риски?

Работа с импортом foreignKeys в django-import-export

Как обрабатывать IncompleteRead: в python

Python: быстрый и эффективный способ записи большого текстового файла

Невозможно загрузить набор данных Iris с помощью sklearn

Как повторить раздел программы, пока вход не будет корректным в python?

python «авто» документирует проект

доверительный интервал с наименьшим значением, подходящим для scipy python

Сравните два кадра данных и фильтруйте согласованные значения

uwsgi + Flask + virtualenv ImportError: нет модуля с именем site

Модуль установки Python pip не найден. Как связать python с местом размещения?

Python Selenium WebDriver. Написание собственного ожидаемого условия

Есть ли способ обходить Python list.append (), становясь все медленнее в цикле, когда список растет?

Градиенты тензорного потока: без автоматической неявной суммы

Время python utc минус 5 минут

Python - лучший язык программирования в мире.