C++ 2D 矢量到 2D pybind11 数组

C++ 2D vector to 2D pybind11 array

本文关键字:2D pybind11 数组 C++      更新时间:2023-10-16

我对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数据结构都可以(例如,列表列表(。

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

提前感谢您的任何帮助。

这里有一些事情发生,但让我们从一个简单的示例开始。以下函数将从硬编码std::vector<std::vector<float>>创建 2D 数组

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属性等(