Pybind Numpy 访问二维/ND 数组 [英] Pybind Numpy access 2D / ND arrays

查看:79
本文介绍了Pybind Numpy 访问二维/ND 数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

pybind 新手 - 阅读文档,但我不了解如何将其应用于 2D 数组.

New to pybind - read the documentation but I do not grasp how to apply it to 2D arrays.

我有两个数组存储 3d 坐标 shape = (10,3)

I have two arrays storing 3d coordinates shape = (10,3)

a = np.zeros(shape=(10,3))
b = np.ones(shape=(10,3)) * 3
c = a + b

现在,使用 pybind,如何在处理 numpy 数组的 C++ 中执行此操作?

Now, using pybind, how do I perform this operation in C++ working on the numpy arrays?

在我阅读的某些文档中,我使用 [] 运算符访问元素,而在其他文档中,我使用 () 访问这些元素.如何分配 3D 矢量?我如何获得指向数组元素的指针以使用步幅进行赋值 - 或者它是否有运算符?

In some documentations I read to access the elements with the [] operator, in others with (). How do assign the 3D vector? How would I get the pointer to the array element to use strides for assignment - or does it have an operator?

推荐答案

PyBind 太棒了,向作者/维护者大声呼喊!你有一个几乎可以工作的例子这里.

PyBind is awesome, shout out to the authors/maintainers! You have an almost working example here.

适应你的问题,它会给出类似的东西(在 El Dude 的评论后编辑答案):

Adapted to your problem it would give something like (edited answer after El Dude's comment):

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


namespace py = pybind11;


py::array_t<double> add_arrays(py::array_t<double> input1, py::array_t<double> input2) {
  py::buffer_info buf1 = input1.request();
  py::buffer_info buf2 = input2.request();

  if (buf1.size != buf2.size) {
    throw std::runtime_error("Input shapes must match");
  }

  /*  allocate the buffer */
  py::array_t<double> result = py::array_t<double>(buf1.size);

  py::buffer_info buf3 = result.request();

  double *ptr1 = (double *) buf1.ptr,
         *ptr2 = (double *) buf2.ptr,
         *ptr3 = (double *) buf3.ptr;
  int X = buf1.shape[0];
  int Y = buf1.shape[1];

  for (size_t idx = 0; idx < X; idx++) {
    for (size_t idy = 0; idy < Y; idy++) {
      ptr3[idx*Y + idy] = ptr1[idx*Y+ idy] + ptr2[idx*Y+ idy];
    }
  }
 
  // reshape array to match input shape
  result.resize({X,Y});

  return result;
}


PYBIND11_MODULE(example, m) {
        m.doc() = "Add two vectors using pybind11"; // optional module docstring

        m.def("add_arrays", &add_arrays, "Add two NumPy arrays");
}

我使用 python2.7 和 gcc v5.4 在 linux 上构建(我必须使用与文档中提供的命令略有不同的命令,因为找不到 Python.h,因此我添加了到 python 2.7 的链接)

That I built on linux with python2.7 and gcc v5.4 using (I had to use a slightly different command than provided in the doc, because Python.h wasn't found, hence I added the link to python 2.7)

c++ -O3 -Wall -shared -std=c++11 -fPIC -I/usr/include/python2.7 -lpython2.7 `python -m pybind11 --includes` example.cpp -o example`python-config --extension-suffix

你会从 python 中调用它

And you'd call it from python with

import numpy as np
import example # [bad] name I chose for my compiled module

a = np.zeros((10,3))
b = np.ones((10,3)) * 3 
c = example.add_arrays(a, b)

print c

希望有帮助.

编辑 - 我创建了一个 github 存储库,其中包含一些基于 PyBind11 的完整示例,应该在所有平台上编译.

EDIT - I've created a github repository containing a few complete examples based on PyBind11 that should compile on all platforms.

这篇关于Pybind Numpy 访问二维/ND 数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆