如何使用 pybind 传递 numpy 数组列表

Posted

技术标签:

【中文标题】如何使用 pybind 传递 numpy 数组列表【英文标题】:Howto pass a list of numpy array with pybind 【发布时间】:2019-08-08 17:15:10 【问题描述】:

我有一个用 python 编写的预处理器。该预处理器计算未知数量的 numpy 数组。它们存储在列表中。为了进一步计算,我需要在 cpp 中阅读这些 numpy 数组列表。我不知道如何将列表的元素转换为数组类型。

main.py

import numpy as np
import myCPPAlgo

my_list = [ np.zeroes(shape=(10, 10), dtype=np.uint32) for _ in range(10)]
myCPPAlgo.call(my_list)

main.cpp

#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>
#include <pybind11/stl.h>

#include <iostream>


namespace py = pybind11;

int call(py::list listOfNumpyArrays)

    for( py::handle array: listOfNumpyArrays)
    
        // howto transform?
        py::array_t<uint32_t> casted_array = ???

        auto requestCastedArray = casted_array.request();
        uint32_t nRows = requestCastedArray.shape[1];
        uint32_t nCols = requestCastedArray.shape[0];
        uint32_t* pBlockedArray = (uint32_t*) requestCastedArray.ptr;
    
    return 0;



PYBIND11_MODULE(myCPPAlgo, m) 
    m.doc() = ""

    m.def("call", &call, "");


如何将 pybind::handle 转换为 py::array_t?

【问题讨论】:

我想另辟蹊径:将数组列表返回给 Python。有什么建议吗? 【参考方案1】:

简单地转换为数组:py::array_t&lt;uint32_t&gt; casted_array = py::cast&lt;py::array&gt;(array);。完整的工作示例(模错误检查:))。

#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>
#include <pybind11/stl.h>

#include <iostream>

namespace py = pybind11;

int call(py::list listOfNumpyArrays)

    for( py::handle array: listOfNumpyArrays)
    
        // howto transform?
        py::array_t<uint32_t> casted_array = py::cast<py::array>(array);

        auto requestCastedArray = casted_array.request();
        uint32_t nRows = requestCastedArray.shape[1];
        uint32_t nCols = requestCastedArray.shape[0];
        uint32_t* pBlockedArray = (uint32_t*) requestCastedArray.ptr;
        std::cerr << " rows x columns = " << nRows << " x " << nCols << std::endl;
        for (int i = 0; i < nCols; ++i) 
            for (int j = 0; j < nRows; ++j) 
                std::cerr << pBlockedArray[i*nRows + j] << " ";
            
            std::cerr << '\n';
        
    
    return 0;


PYBIND11_MODULE(myCPPAlgo, m) 
    m.doc() = "";
    m.def("call", &call, "");

和测试代码:

import numpy as np
import myCPPAlgo

my_list = [ np.ones(shape=(3, 10), dtype=np.uint32) for _ in range(10)]
my_list[9][1, 0] = 42
myCPPAlgo.call(my_list)

【讨论】:

非常感谢。我很确定,我尝试过某种 py::cast。不确定差异在哪里。

以上是关于如何使用 pybind 传递 numpy 数组列表的主要内容,如果未能解决你的问题,请参考以下文章

Pybind11:从 C++ 端创建并返回 numpy 数组

从 python 传递到 C++ 的数组中未映射的内存访问

如何在pybind11中将共享指针列表传递给c++对象

Pybind11 默认参数 numpy 数组或无

使用 carma(犰狳矩阵和 numpy 数组)用 pybind11 包装 c++ 类时出错

如何通过 cython 将 numpy 数组列表传递给 c++