我刚刚了解到Python Buffer Protocol,我想利用它从原始数据创建 pythonnumpy数组。C++我可以直接使用 pybind11 或 c++ python lib,但没有其他绑定生成器=/
阅读pybind11 文档并对其进行实验,我们似乎可以轻松地从简单的 C++ 结构(例如,std::vector<int>或struct具有普通旧数据类型,如int、float等)生成带有缓冲区协议的 python 绑定。然而,向更复杂的结构添加缓冲协议是不可能的,或者没有很好的记录。对于我的用例,我将 pybind a std::vector<struct Sequence>,Sequence定义如下:
struct Sequence {
std::vector<float> feature;
std::vector<int> label;
}
Run Code Online (Sandbox Code Playgroud)
一旦在 C++ 端实现了与缓冲区协议的 python 绑定,在 Python 端我可以做
for seq in vector_sequence:
feature_data=numpy.array(seq.feature, copy=False)`
label_data=numpy.array(seq.label, copy=False)`.
Run Code Online (Sandbox Code Playgroud)
在上面的循环中,vector_sequence是 C++ 的不透明绑定std::vector<Sequence>,并且seq是 a Sequence,它保存我想要用作numpy数组输入的两个向量,而无需将数据从 C++ 复制到 Python。
有谁知道 pybind11 或 c++ python lib 是否支持此功能?
谢谢!
我成功了!Sequence我了解到,如果我想防止复制 和feature成员label,而不是Sequence整个实际的类,则不必为类实现协议缓冲区。例子:
PYBIND11_MAKE_OPAQUE(std::vector<Sequence>);
py::bind_vector<std::vector<int>>(m, "VectorInt", py::buffer_protocol());
py::bind_vector<std::vector<float>>(m, "VectorFloat", py::buffer_protocol());
py::class_<SequenceReader>(m, "SequenceReader").def("read_sequences", &SequenceReader::read_sequences, py::return_value_policy::take_ownership);
Run Code Online (Sandbox Code Playgroud)
重要的是要注意我正在使用pybind11/numpy.h并PYBIND11_MAKE_OPAQUE防止复制