我正在尝试使用pybind 11编写一个python插件,并在将数据从numpy转换为std::vector类型时遇到了问题。python函数的调用是通过以下形式的字典实现的:{"varname": numpy_array}
我所有的试验都以一个类似RuntimeError: Unable to cast Python instance of type <class 'numpy.ndarray'> to C++ type 'std::vector<float, std::allocator<float> >'
的投射错误的变体结束
解析函数如下所示:
std::vector<float> Plg::process(py::dict &inputs)
{
std::vector<std::string> keys;
//len(data) == len(keys)
std::vector<std::vector<std::vector<float>>> data; //!!! does not work
for (auto item : inputs)
{
std::string k = py::cast<std::string>(item.first);
keys.push_back(k);
std::vector<std::vector<float>> d = py::cast<std::vector<std::vector<float>>>(item.second);
data.push_back(d);
}
//_process(data); - call to actual function, replace with dummy:
std::vector<float> results;
results.push_back(10.2);
return results;
}
item
对象的类型是pybind 11::handle,我似乎找不到它的成员的明确列表。在正常情况下我只会让我的函数接受py::array_t,但遗憾的是,输入必须是一个带有字符串键和半任意numpy数组的字典:
std::vector<float> Plg::doit(py::array_t<float, py::array::c_style | py::array::forcecast>
&input_vector)
{
std::vector<float> array_vector(input_vector.size());
std::memcpy(array_vector.data(), input_vector.data()
, input_vector.size()*sizeof(float));
std::vector<float> results = _process(array_vector);
return results;
}
然而,上面的方法只适用于在Python中预先转换为数组的数据(平面numpy数组)。我发现的所有线程都在处理一个相反的问题--从vector到numpy,这不是我的情况。
我的问题是双重的,首先
1.如何解压缩任意numpy数组并将其放入平面std::vector中?
1.有没有更聪明的方法不需要memcpy?
我相信有一个简单的解决方案,我只是不知道,将大大感谢帮助
更新
我的问题来自于numpy容忍的不同输入大小--输入的数据可以是维度为(10,10,2)或(200,)甚至(2,)的数组--它最终应该都是内部的float向量--py::array_t似乎处理得很好
1条答案
按热度按时间nvbavucw1#
拆包有点简单,但我不确定它的效率。技巧是使用
py::array_t
的属性以及它如何处理任意numpy数组。问题是,**buffer对象没有有效的end()**方法(开始()返回正确的值,end()返回null)如果pybind附带更深入的示例就更好了,但总的来说,这是一个很棒的库。