【问题标题】:C++ 2D vector to 2D pybind11 arrayC++ 2D 向量到 2D pybind11 数组
【发布时间】:2020-09-07 06:04:58
【问题描述】:

我对 C++ 还很陌生,并且在 pybind 上苦苦挣扎。我根本不知道如何说服 pybind 将 2D 矢量从 C++ 转换为 python 可读格式。

这就是我想到的代码:

py::array_t<float> to_matrix(std::vector<std::vector<float>> &vals)
{
    int N = vals.size();
    int M = 6;
    py::array_t<float>({N, M}) arr;
    for (int i = 0; (i < N); i++)
    {
        for (int j = 0; (j < M); j++)
        {
            arr[i][j] = vals[i][j];
        };
    };
    return arr;
};

C++ 的输入是一个包含 N 行 6 列的向量,只是一个很长的数据点列表。理想情况下,我希望将输出作为 numpy 数组,但任何 python 数据结构都可以(例如,列表列表)。

文档使它听起来很简单,但我无法弄清楚。我做错了什么?

提前感谢您的帮助。

【问题讨论】:

    标签: python c++ arrays numpy pybind11


    【解决方案1】:

    这里发生了一些事情,但让我们从一个最小的示例开始。以下函数将从硬编码的std::vector&lt;std::vector&lt;float&gt;&gt; 创建一个二维数组

    py::array_t<float> to_matrix()
    {
        std::vector<std::vector<float>> vals = {
            {1, 2, 3, 4, 5},
            {6, 7, 8, 9, 10},
            {11, 12, 13, 14, 15}
        };
    
        size_t N = vals.size();
        size_t M = vals[0].size();
    
        py::array_t<float, py::array::c_style> arr({N, M});
    
        auto ra = arr.mutable_unchecked();
    
        for (size_t i = 0; i < N; i++)
        {
            for (size_t j = 0; j < M; j++)
            {
                ra(i, j) = vals[i][j];
            };
        };
    
        return arr;
    };
    
    PYBIND11_MODULE(foo, m)
    {
        m.def("to_matrix", &to_matrix);
    }
    

    需要注意两点,首先数组形状是数组的构造函数参数。其次是使用mutable_unchecked 获取可用于进行分配的代理对象。

    在您的情况下,向量的向量将来自 C++ 代码中的其他地方。

    但请注意,pybind11 还提供了用于包装容器的样板,例如 std::vector。这些在标题pybind11/stl_bind.h 中可用,并允许您执行此操作

    std::vector<std::vector<float>> make_vector()
    {
        std::vector<std::vector<float>> vals = {
            {1, 2, 3, 4, 5},
            {6, 7, 8, 9, 10},
            {11, 12, 13, 14, 15}
        };
    
        return vals;
    
    }
    
    PYBIND11_MODULE(foo, m)
    {
        py::bind_vector<std::vector<std::vector<float>>>(m, "FloatVector2D");
        m.def("make_vector", &make_vector);
    }
    

    虽然这样的对象不会完全等同于 numpy 数组(没有 shape 属性等)

    【讨论】:

    • 谢谢,这正是我一直在寻找的并完美解决了我的问题 :) “FloatVector2D”是一个特殊的名称,以便 pybind 使用正确的绑定还是任意命名?我只是找不到太多关于此的文档
    • 不,完全随意,
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-07
    • 2017-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多