当前位置: 首页 > 工具软件 > NumCpp > 使用案例 >

NumCpp安装与使用

姜磊
2023-12-01

1. 安装

git clone https://github.com/dpilger26/NumCpp
cd NumCpp
mkdir build && cd build
cmake ..
sudo cmake --build . --target install

2. cmake编写

find_package(NumCpp REQUIRED)

target_link_libraries(${PROJECT_NAME}
    NumCpp::NumCpp
)

3. 使用

NumCpp中的主要数据结构NdArray。它本质上是一个 2D 数组类,一维数组实现为1xN数组。还有一个DataCube类作为便利容器提供,用于存储2D数组NdArray,但它通过简单容器的用途有限。

NumpyNumCpp
a = np.array([[1, 2], [3, 4], [5, 6]])nc::NdArray<int> a = { {1, 2}, {3, 4}, {5, 6} }
a.reshape([2, 3])a.reshape(2, 3)
a.astype(np.double)a.astype<double>()

示例

#include"NumCpp.hpp"
#include"boost/filesystem.hpp"
#include<iostream>
using namespace std;

int main()
{
    // 简单示例
    int a = 10;
    // 生成2×2的int类型矩阵(NdArray)
    nc::NdArray<int> a0 = { {1, 2}, {3, 4} };
    // 生成3×2的int类型矩阵(NdArray)
    nc::NdArray<int> a1 = { {1, 2}, {3, 4}, {5, 6} };
    
    cout << "查看a数据类型:\n" << typeid(a).name() << endl;
    cout << "查看a0数据类型:\n"<< typeid(a0).name() << endl;
    cout << "a0:\n" << a0 << endl;
    cout << "a1:\n" << a1 << endl;

    a1.reshape(2, 3);
    cout << "改变a1形状(2×3):\n" << a1 << endl;

    auto a2 = a1.astype<double>();
    cout << "int类型转换duoble类型:\n" << typeid(a2).name() << endl;
    cout << "a2:\n" << a1 << endl;
 
    return 0;
}

结果

查看a数据类型:
int
查看a0数据类型:
class nc::NdArray<int,class std::allocator<int> >
a0:
[[1, 2, ]
[3, 4, ]]

a1:
[[1, 2, ]
[3, 4, ]
[5, 6, ]]

改变a1形状(2×3):
[[1, 2, 3, ]
[4, 5, 6, ]]

int类型转换duoble类型:
class nc::NdArray<double,class std::allocator<double> >
a2:
[[1, 2, 3, ]
[4, 5, 6, ]]

3.1. 矩阵初始化

NumCpp 提供了许多初始化函数,它们返回NdArray

NumPyNumCpp
np.linspace(1, 10, 5)nc::linspace<dtype>(1, 10, 5)
np.arange(3, 7)nc::arrange<dtype>(3, 7)
np.eye(4)nc::eye<dtype>(4)
np.zeros([3, 4])nc::zeros<dtype>(3, 4)
nc::NdArray<dtype>(3, 4) a = 0
np.ones([3, 4])nc::ones<dtype>(3, 4)
nc::NdArray<dtype>(3, 4) a = 1
np.nans([3, 4])nc::nans<dtype>(3, 4)
nc::NdArray<dtype>(3, 4) a = nc::constants::nan
np.empty([3, 4])nc::empty<dtype>(3, 4)
nc::NdArray<dtype>(3, 4) a;

示例

#include"NumCpp.hpp"
#include"boost/filesystem.hpp"
#include<iostream>
using namespace std;

int main()
{
    // 矩阵初始化
    //在指定的1-10间隔内返回均匀间隔的5个数
    auto a1 = nc::linspace<int>(1, 10, 5);
    //在给定间隔内返回均匀间隔的值
    auto a2 = nc::arange<int>(3, 7);
    //单位矩阵
    auto a3 = nc::eye<int>(4);
    //全零矩阵
    auto a4 = nc::zeros<int>(3, 4);
    auto a5 = nc::NdArray<int>(3, 4) = 0;
    //全1矩阵
    auto a6 = nc::ones<int>(3, 4);
    auto a7 = nc::NdArray<int>(3, 4) = 1;
    //全nan矩阵
    auto a8 = nc::nans(3, 4);
    auto a9 = nc::NdArray<double>(3, 4) = nc::constants::nan;
    //空矩阵
    auto a10 = nc::empty<int>(3, 4);
    auto a11 = nc::NdArray<int>(3, 4);

    cout << "a1:\n" << a1 << endl;
    cout << "a2:\n" << a2 << endl;
    cout << "a3:\n" << a3 << endl;
    cout << "a4:\n" << a4 << endl;
    cout << "a5:\n" << a5 << endl;
    cout << "a6:\n" << a6 << endl;
    cout << "a7:\n" << a7 << endl;
    cout << "a8:\n" << a8 << endl;
    cout << "a9:\n" << a9 << endl;
    cout << "a10:\n" << a10 << endl;
    cout << "a11:\n" << a11 << endl;
 
    return 0;
}

结果

a1:
[[1, 3, 5, 7, 10, ]]

a2:
[[3, 4, 5, 6, ]]

a3:
[[1, 0, 0, 0, ]
[0, 1, 0, 0, ]
[0, 0, 1, 0, ]
[0, 0, 0, 1, ]]

a4:
[[0, 0, 0, 0, ]
[0, 0, 0, 0, ]
[0, 0, 0, 0, ]]

a5:
[[0, 0, 0, 0, ]
[0, 0, 0, 0, ]
[0, 0, 0, 0, ]]

a6:
[[1, 1, 1, 1, ]
[1, 1, 1, 1, ]
[1, 1, 1, 1, ]]

a7:
[[1, 1, 1, 1, ]
[1, 1, 1, 1, ]
[1, 1, 1, 1, ]]

a8:
[[nan, nan, nan, nan, ]
[nan, nan, nan, nan, ]
[nan, nan, nan, nan, ]]

a9:
[[nan, nan, nan, nan, ]
[nan, nan, nan, nan, ]
[nan, nan, nan, nan, ]]

a10:
[[-1030135744, 741, -1030129280, 741, ]
[1, 1, 1, 1, ]
[1, 1, 1, 1, ]]

a11:
[[-1030138000, 741, -1030129280, 741, ]
[-1030142624, 741, -1030142624, 741, ]
[-1030142624, 741, -1030142624, 741, ]]

3.2. 切片与广播

NumCpp 提供类似 NumPy 的切片与广播。

NumPyNumCpp
a[2, 3]a(2, 3)
a[2:5, 5:8]a(nc::Slice(2, 5), nc::Slice(5, 8))
a({2, 5}, {5, 8})
a[:, 7]a(a.rSlice(), 7)
a[a > 5]a[a > 0]
a[a > 5] = 0a.putMask(a > 5, 0)

示例

#include"NumCpp.hpp"
#include"boost/filesystem.hpp"
#include<iostream>
using namespace std;

int main()
{
    // 切片与广播
    //随机生成6×6的int矩阵
    auto a1 = nc::random::randInt<int>({ 6, 6 }, 0, 100);
    //获取第3行第4列的值
    auto value = a1(2, 3);
    //获取第3-5行和第3-5列的值
    auto slice = a1({ 2, 5 }, { 2, 5 });
    //获取第3、5行和第3、5列的值
    auto slice1 = a1({ 2, 5 ,2}, { 2, 5 ,2});
    //获取第6列的值
    auto rowSlice = a1(a1.rSlice(), 5);
    //获取大于50的值
    auto values = a1[a1 > 50];

    cout << "a1:\n" << a1 << endl;
    cout << "value:\n" << value << endl;
    cout << "slice:\n" << slice << endl;
    cout << "slice1:\n" << slice1 << endl;
    cout << "rowSlice:\n" << rowSlice << endl;
    cout << "values :\n" << values << endl;

    //将大于50的值替换为666
    a1.putMask(a1 > 50, 666);
    cout << "a1:\n" << a1 << endl;

    return 0;
}

结果

a1:
[[30, 8, 20, 22, 96, 98, ]
[29, 78, 56, 2, 33, 7, ]
[0, 67, 68, 32, 62, 31, ]
[57, 13, 58, 34, 25, 66, ]
[11, 5, 78, 30, 80, 41, ]
[56, 98, 73, 90, 76, 47, ]]

value:
32
slice:
[[68, 32, 62, ]
[58, 34, 25, ]
[78, 30, 80, ]]
slice1:
[[68, 62, ]
[78, 80, ]]

rowSlice:
[[98, ]
[7, ]
[31, ]
[66, ]
[41, ]
[47, ]]

values :
[[96, 98, 78, 56, 67, 68, 62, 57, 58, 66, 78, 80, 56, 98, 73, 90, 76, ]]

a1:
[[30, 8, 20, 22, 666, 666, ]
[29, 666, 666, 2, 33, 7, ]
[0, 666, 666, 32, 666, 31, ]
[666, 13, 666, 34, 25, 666, ]
[11, 5, 666, 30, 666, 41, ]
[666, 666, 666, 666, 666, 47, ]]

参考文献

NumCpp, Numpy for C++

NumCpp基础教程(上)_陨星落云的博客-CSDN博客_numcpp

 类似资料: