C++ 二维向量到二维 pybind11 数组
C++ 2D vector to 2D pybind11 array
我是 C++ 的新手,在使用 pybind 时遇到了困难。我根本不知道如何说服 pybind 将二维向量从 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 数据结构都可以(例如,列表列表)。
文档听起来很简单,但我想不通。我做错了什么?
提前感谢您的帮助。
这里发生了一些事情,但让我们先从一个最小的示例开始。以下函数将从 hard-coded std::vector<std::vector<float>>
创建一个二维数组
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
获得可用于进行分配的代理 object。
在您的情况下,向量的向量将来自您的 C++ 代码中的其他地方。
但请注意,pybind11 还提供了用于包装容器的样板,例如 std::vector
。这些在 header 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);
}
这样的 object 不会完全等同于 numpy 数组(没有 shape
属性等)
我是 C++ 的新手,在使用 pybind 时遇到了困难。我根本不知道如何说服 pybind 将二维向量从 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 数据结构都可以(例如,列表列表)。
文档听起来很简单,但我想不通。我做错了什么?
提前感谢您的帮助。
这里发生了一些事情,但让我们先从一个最小的示例开始。以下函数将从 hard-coded std::vector<std::vector<float>>
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
获得可用于进行分配的代理 object。
在您的情况下,向量的向量将来自您的 C++ 代码中的其他地方。
但请注意,pybind11 还提供了用于包装容器的样板,例如 std::vector
。这些在 header 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);
}
这样的 object 不会完全等同于 numpy 数组(没有 shape
属性等)