Boost C++ 库

...世界上最受推崇和设计最精湛的 C++ 库项目之一。 Herb SutterAndrei Alexandrescu,《C++ 编码标准

C++ Boost

(NumPy)


创建 ndarrays

Boost.Numpy 库公开了许多创建 ndarrays 的方法。ndarray 可以通过多种方式创建,包括空数组和零填充数组。ndarray 也可以从任意 Python 序列以及数据和数据类型创建。

本教程将向您介绍一些创建 ndarrays 的方法。这里涵盖的方法包括从任意 Python 序列以及 C++ 容器创建 ndarrays,使用单位步长和非单位步长。

首先,和之前一样,初始化必要的命名空间和运行时

#include <boost/python/numpy.hpp>
#include <iostream>

namespace p = boost::python;
namespace np = boost::python::numpy;

int main(int argc, char **argv)
{
  Py_Initialize();
  np::initialize();

现在让我们从一个简单的元组创建一个 ndarray。我们首先创建一个元组对象,然后将其传递给 array 方法,以生成必要的元组

p::object tu = p::make_tuple('a','b','c');
np::ndarray example_tuple = np::array(tu);

现在让我们用列表尝试同样的操作。我们创建一个空列表,使用 append 方法添加一个元素,然后和之前一样,调用 array 方法

p::list l;
l.append('a');
np::ndarray example_list = np::array (l);

可选地,我们还可以为数组指定一个数据类型 (dtype)

np::dtype dt = np::dtype::get_builtin<int>();
np::ndarray example_list1 = np::array (l,dt);

我们还可以通过提供数据数组和一些其他参数来创建数组。

首先,创建整数数组

int data[] = {1,2,3,4,5};

创建函数所需的形状 (shape) 和步长 (strides)

p::tuple shape = p::make_tuple(5);
p::tuple stride = p::make_tuple(sizeof(int));

这里,形状是 (4,),步长是 sizeof(int)。步长是在构造 ndarray 时,为了到达下一个期望的元素必须移动的字节数。

该函数还需要一个所有者 (owner),以跟踪传递的数据数组。传递 None 是危险的

p::object own;

from_data 函数接受数据数组、数据类型 (datatype)、形状 (shape)、步长 (stride) 和所有者 (owner) 作为参数,并返回一个 ndarray

np::ndarray data_ex1 = np::from_data(data,dt, shape,stride,own);

现在让我们打印我们创建的 ndarray

std::cout << "Single dimensional array ::" << std::endl
          << p::extract<char const *>(p::str(data_ex)) << std::endl;

让我们让它更有趣一点。让我们使用非单位步长从多维数组创建一个 3x2 的 ndarray

首先让我们创建一个 3x4 的 8 位整数数组

uint8_t mul_data[][4] = {{1,2,3,4},{5,6,7,8},{1,3,5,7}};

现在让我们创建一个 3x2 元素的数组,从每行中选择第一个和第三个元素。为此,形状将是 3x2。步长将是 4x2,即移动 4 个字节到下一个期望的行,移动 2 个字节到下一个期望的列

shape = p::make_tuple(3,2);
stride = p::make_tuple(sizeof(uint8_t)*2,sizeof(uint8_t));

获取内置 8 位整数数据类型的 NumPy 数据类型 (dtype)

np::dtype dt1 = np::dtype::get_builtin<uint8_t>();

现在让我们首先创建并打印出 ndarray 的原样。请注意我们如何在函数中直接传递形状和步长,以及所有者。最后一部分可以这样做,因为我们没有任何用途来操作“owner”对象

np::ndarray mul_data_ex = np::from_data(mul_data, dt1,
                                        p::make_tuple(3,4),
                                        p::make_tuple(4,1),
                                        p::object());
std::cout << "Original multi dimensional array :: " << std::endl
          << p::extract<char const *>(p::str(mul_data_ex)) << std::endl;

现在使用形状和步长创建新的 ndarray,并打印出我们使用非单位步长创建的数组

  mul_data_ex = np::from_data(mul_data, dt1, shape, stride, p::object());
  std::cout << "Selective multidimensional array :: "<<std::endl
            << p::extract<char const *>(p::str(mul_data_ex)) << std::endl ;
}

注意

如果形状和相应步长指示的元素数量不匹配,from_data 方法将抛出 error_already_set 错误。