创建 ndarrays
Boost.Numpy 库提供了许多创建 ndarrays 的方法。ndarray 可以通过多种方式创建,包括空数组和全零数组。ndarray 还可以从任意 Python 序列以及数据和 dtypes 创建。
本教程将介绍创建 ndarrays 的一些方法。这里介绍的方法包括从任意 Python 序列创建 ndarrays,以及从 C++ 容器创建,同时使用单位步幅和非单位步幅。
首先,一如既往,初始化必要的命名空间和运行时。
#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));
这里,shape 是 (4,),stride 是 `sizeof(int)`。步幅是在构造 ndarray 时,为了获取下一个期望的元素而必须跳过的字节数。
该函数还需要一个 owner,来跟踪传递的数据数组。传递 None 是危险的。
p::object own;
from_data 函数以数据数组、数据类型、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。
首先,创建一个包含 8 位整数的 3x4 数组。
uint8_t mul_data[][4] = {{1,2,3,4},{5,6,7,8},{1,3,5,7}};
现在,让我们创建一个包含 3x2 个元素的数组,从每一行中选择第一个和第三个元素。为此,shape 将是 3x2。strides 将是 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。请注意,我们可以直接在函数中传递 shape 和 strides,以及 owner。最后一部分可以这样做,因为我们不需要操作“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;
现在,使用 shape 和 strides 创建新的 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 ;
}
注意
如果 shape 和相应的 strides 所规定的元素数量不匹配,from_data 方法将抛出 `error_already_set`。