C++的NumPy样式数组?

Lla*_*don 62 c++ arrays dynamic-arrays

是否有任何C++(或C)库具有类似NumPy的数组,支持切片,矢量化操作,逐元素添加和减去内容等?

Qua*_*ant 42

试试xtensor.(参见NumPy到Xtensor备忘单).

xtensor是一个C++库,用于使用多维数组表达式进行数值分析.

xtensor提供

  • 一个可扩展的表达系统,可以实现numpy风格的广播.
  • 遵循C++标准库惯用语的API.
  • 用于操纵数组表达式和构建xtensor的工具.

初始化2-D数组并计算其中一行和一维数组的总和.

#include <iostream>
#include "xtensor/xarray.hpp"
#include "xtensor/xio.hpp"

xt::xarray<double> arr1
  {{1.0, 2.0, 3.0},
   {2.0, 5.0, 7.0},
   {2.0, 5.0, 7.0}};

xt::xarray<double> arr2
  {5.0, 6.0, 7.0};

xt::xarray<double> res = xt::view(arr1, 1) + arr2;

std::cout << res;
Run Code Online (Sandbox Code Playgroud)

输出

{7, 11, 14}
Run Code Online (Sandbox Code Playgroud)

初始化一维数组并将其重新整形.

#include <iostream>
#include "xtensor/xarray.hpp"
#include "xtensor/xio.hpp"

xt::xarray<int> arr
  {1, 2, 3, 4, 5, 6, 7, 8, 9};

arr.reshape({3, 3});

std::cout << arr;
Run Code Online (Sandbox Code Playgroud)

输出

{{1, 2, 3},
 {4, 5, 6},
 {7, 8, 9}}
Run Code Online (Sandbox Code Playgroud)

  • @Llamgeddon 你认为这应该是选定的答案吗? (2认同)

noj*_*han 40

以下是一些可满足您需求的免费软件.

  1. GNU科学图书馆是用C编写因此,一个GPL软件,它具有类似C的配置和编程的方式(指针等).使用GSLwrap,您可以使用C++编程方式,同时仍然使用GSL.GSL有一个BLAS实现,但如果你想要更多的性能,你可以使用ATLAS而不是默认的CBLAS.

  2. 升压/ uBLAS库库是一个BSL库,用C++编写和分布式作为升压包.它是一种C++ - 实现BLAS标准的方式.uBLAS带有一些线性代数函数,并且有一个实验性的绑定到ATLAS.

  3. eigen是一个用C++编写的线性代数库,分布在LGPL3(或GPL2)下.它是一种C++编程方式,但比其他两种方式更集成(更多算法和数据结构可用).Eigen 声称比上面的BLAS实现更快,而不遵循事实上的标准BLAS API.Eigen似乎没有在并行实现上投入大量精力.

  4. Armadillo是用于C++的LGPL3库.它具有LAPACK(numpy使用的库)的绑定.它使用递归模板和模板元编程,这是一个好点(我不知道其他库是否也在做它?).

如果您只想获得数据结构和基本线性代数,这些替代方案非常好.根据您对样式,许可证或系统管理员挑战的喜好(安装LAPACK等大型库可能很困难),您可以选择最适合您需求的库.

  • 可悲的是,这些都没有提供像numpy数组那样通用和方便的东西.Numpy数组是任意维的,支持诸如`a [:4,:: - 1,:,19] = b [None,-5:,None]`或`a [a> 5] = 0`之类的东西,以及可用的大量数组和索引操作函数.我真的希望有一天有人为C++制作类似的东西. (13认同)
  • 信不信由你,我的答案是我个人以前搜索的结果.我相信收集帮助我做出选择的信息会引起一些兴趣.我不确定在答案中传播几个信息会更好.如果你更关心道德而不是效率,你仍然可以支持每个人. (11认同)
  • OpenCV 还有一个 Matrix 类型,可以有任意的维度大小;列/行范围(`a.colRange(4,7).rowRange(4,8)` for `a[4:7,4,8]`)和条件掩码(`a.setTo(cv::Scalar( 0), a&gt;5)` 对于 `a[a&gt;5]=0`) (4认同)
  • @amaurea在下面的xtensor上查看答案,这将启用所有上述功能。 (2认同)
  • 我不得不在最近的一个项目中使用 Eigen,我不得不说,虽然它看起来很高效,但语法绝对是糟糕的。没有任何令人惊奇的 Python 切片语法可用。例如,如果您有一个一维向量 x 并且想要操作前 n 个元素,则必须使用 x.head(n)。甚至不要问如何操作 x 的任意切片,您将需要一个很好的旧 for 循环来做到这一点。这只是我能举出的众多笨拙和不方便的例子之一。 (2认同)

Ian*_*anH 7

DyND被设计成一个类似NumPy的C++库.广播,算术运算符和切片等都可以正常工作.另一方面,它仍然是非常实验性的,许多功能尚未实现.

这是使用DyND数组在C++中使用de Casteljau算法的简单实现:

#include <iostream>
#include <dynd/array.hpp>

using namespace dynd;

nd::array decasteljau(nd::array a, double t){
    size_t e = a.get_dim_size();
    for(size_t i=0; i < e-1; i++){
        a = (1.-t) * a(irange()<(e-i-1)) + t * a(0<irange());
    }
    return a;
}

int main(){
    nd::array a = {1., 2., 2., -1.};
    std::cout << decasteljau(a, .25) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

我在一段时间写了一篇博文,其中有更多的例子,并且对Fortran 90的语法,C++的DyND和Python的NumPy进行了并列比较.

免责声明:我是目前的DyND开发人员之一.


Say*_*Dey 7

这是一个老问题了。还是想回答一下。想法可能对很多人有帮助,尤其是 C++ 中的 pydevs 编码。

如果您已经使用过 python numpy,那么NumCpp是一个不错的选择。它的语法很简约,并且具有与 py numpy 类似的函数或方法。

自述文件中的比较部分也非常非常酷。

Cpp数

nc::NdArray<int> arr = {{4, 2}, {9, 4}, {5, 6}};
arr.reshape(5, 3);
arr.astype<double>();
Run Code Online (Sandbox Code Playgroud)


小智 6

使用 LibTorch(C++ 的 PyTorch 前端)并感到高兴。