python - 将 std::vector 作为 numpy 数组返回给 python

标签 python c++ numpy vector pybind11

使用 Pybind11,我试图将一个 numpy 数组传递给 c++ 到一个 std::vector 中,将它乘以 2,然后返回这个 std::vector 到python 作为一个 numpy 数组。

我已经迈出了第一步,但第三步却在做一些奇怪的事情。为了将它传回,我使用了:订单。

例如,我有一个数组:

[[ 0.78114362  0.06873818  1.00364053  0.93029671]
 [ 1.50885413  0.38219005  0.87508337  2.01322396]
 [ 2.19912915  2.47706644  1.16032292 -0.39204517]]

代码返回:

array([[ 1.56228724e+000,  3.01770826e+000,  4.39825830e+000,
         5.37804299e+161],
       [ 1.86059342e+000,  4.02644793e+000, -7.84090347e-001,
         1.38298992e-309],
       [ 1.75016674e+000,  2.32064585e+000,  0.00000000e+000,
         1.01370255e-316]])

我已阅读文档,但我无法理解其中的大部分内容。

这里有一个例子可以尝试:

#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>
#include <pybind11/stl.h>
#include <Python.h>
namespace py = pybind11;
py::module nn = py::module::import("iteration");


py::array nump(py::array arr){

    auto arr_obj_prop = arr.request();
    //initialize values
    double *vals = (double*) arr_obj_prop.ptr;

    unsigned int shape_1 = arr_obj_prop.shape[0];
    unsigned int shape_2 = arr_obj_prop.shape[1];


    std::vector<std::vector <double>> vect_arr( shape_1, std::vector<double> (shape_2));

    for(unsigned int i = 0; i < shape_1; i++){
      for(unsigned int j = 0; j < shape_2; j++){
        vect_arr[i][j] = vals[i*shape_1 + j*shape_2] * 2;
      }
    }   

    py::array ret =  py::cast(vect_arr); //py::array(vect_arr.size(), vect_arr.data());
    return ret;

}

PYBIND11_MODULE(iteration_mod, m) {

    m.doc() = "pybind11 module for iterating over generations";

    m.def("nump", &nump,
      "the function which loops over a numpy array");
}

和 Python 代码:

import numpy as np
import iteration_mod as i_mod

class iteration(object):
    def __init__(self):
        self.iterator = np.random.normal(0,1,(3,4))

    def transform_to_dict(self):
        self.dict = {}
        for i in range(self.iterator.shape[0]):
            self.dict["key_number_{}".format(i)] = self.iterator[i,:]
        return self.dict

    def iterate_iterator(self):
        return i_mod.nump(self.iterator)

    def iterate_dict(self):
        return i_mod.dict(self)

a = iteration()
print(a.iterator)
print(a.iterate_iterator())

所有这些都是用:c++ -O3 -Wall -fopenmp -shared -std=c++11 -fPIC python3 -m pybind11 --includes iteration_mod.cpp -o iteration_mod .so

最佳答案

std::vector<std::vector<double>>没有二维内置数组的内存布局,因此 py::array(vect_arr.size(), vect_arr.data());将不起作用。

看起来 py::cast 确实进行了正确的复制转换并将值从 vector 传播到新的 numpy 数组,但是这一行:

vect_arr[i][j] = vals[i*shape_1 + j*shape_2] * 2;

是不对的。应该是:

vect_arr[i][j] = vals[i*shape_2 + j] * 2;

关于python - 将 std::vector 作为 numpy 数组返回给 python,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58756764/

相关文章:

python - AWS lambda 克隆 git 存储库并使 zip 无法在 s3 中上传

c++ - 您如何找到哪个 .lib 文件对应哪个函数?

c++ - 为什么每当我创建一个新的 C++ 项目时 Eclipse 默认为 Debug模式?

python - 元组索引 numpy 数组的奇怪行为

Python:读取时间为小时、分钟和秒的文本文件;和角度,弧分和弧秒

python - Airflow 任务信息 - 任务退出并返回代码 -9

virtualization - 我可以使用带有 QEMU 后端的 libvirt Python 模块注册事件回调吗?

python - 使用用户输入中断 while 循环(通过 arduino 和 python 2.7 控制 neopixels)

Python 在 for 循环和数百个属性查找上速度很慢。使用 Numba 吗?

c++ - 为什么我的程序在管道读取过程中卡住?