Как получить данные из np.array в std::vector в C++, используя <numpy / arrayobject.h>?
Это мой первый вопрос на этом сайте.
Прежде всего, мне нужно сделать модуль с одной функцией для Python на C++, который должен работать с Numpy, используя <numpy/arrayobject.h>
, Эта функция принимает один числовой массив и возвращает два пустых массива. Все массивы одномерные.
Первый вопрос: как получить данные из массива NumPy? Я хочу собрать информацию из массива в std::vector, чтобы потом я мог легко работать с ней C++.
Второе: я прав, что функция должна возвращать кортеж массивов, тогда пользователь моего модуля может написать так на python:arr1, arr2 = foo(arr)
? И как вернуть так?
Большое спасибо.
1 ответ
NumPy включает в себя множество функций и макросов, которые облегчают доступ к данным ndarray
объект в расширении C или C++. Учитывая 1D ndarray
называется v
можно получить доступ к элементу i
с PyArray_GETPTR1(v, i)
, Так что если вы хотите скопировать каждый элемент в массиве в std::vector
одного и того же типа, вы можете перебирать каждый элемент и копировать его, вот так (я предполагаю, что массив double
s):
npy_intp vsize = PyArray_SIZE(v);
std::vector<double> out(vsize);
for (int i = 0; i < vsize; i++) {
out[i] = *reinterpret_cast<double*>(PyArray_GETPTR1(v, i));
}
Можно также сделать большую часть memcpy
-подобная операция, но имейте ввиду, что NumPy ndarray
s могут быть выровнены неправильно для типа данных, иметь не собственный порядок байтов или другие тонкие атрибуты, которые делают такие копии менее желательными. Но при условии, что вы знаете об этом, можно сделать:
npy_intp vsize = PyArray_SIZE(v);
std::vector<double> out(vsize);
std::memcpy(out.data(), PyArray_DATA(v), sizeof(double) * vsize);
Используя любой подход, out
теперь содержит копию ndarray
данные, и вы можете манипулировать ими так, как вам нравится. Имейте в виду, что, если вам не нужны данные как std::vector
API-интерфейс NumPy C может прекрасно использоваться в вашем расширении для доступа к данным и манипулирования ими. То есть, если вам не нужно передавать данные в какую-то другую функцию, которая должна std::vector
или вы хотите использовать код библиотеки C++, который опирается на std::vector
Я хотел бы рассмотреть всю вашу обработку непосредственно на нативных типах массивов.
Что касается вашего последнего вопроса, один обычно использует PyArg_BuildValue
построить кортеж, который возвращается из ваших функций расширения. Ваш кортеж будет содержать только два ndarray
объекты.