创建 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
错误。