git clone https://github.com/dpilger26/NumCpp
cd NumCpp
mkdir build && cd build
cmake ..
sudo cmake --build . --target install
find_package(NumCpp REQUIRED)
target_link_libraries(${PROJECT_NAME}
NumCpp::NumCpp
)
NumCpp中的主要数据结构是NdArray
。它本质上是一个 2D 数组类,一维数组实现为1xN数组。还有一个DataCube
类作为便利容器提供,用于存储2D数组NdArray
,但它通过简单容器的用途有限。
Numpy | NumCpp |
---|---|
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, ]]
NumCpp 提供了许多初始化函数,它们返回NdArray
。
NumPy | NumCpp |
---|---|
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, ]]
NumCpp 提供类似 NumPy 的切片与广播。
NumPy | NumCpp |
---|---|
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] = 0 | a.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, ]]