NumCpp库使用教程:从基础操作到高级功能全面解析
NumCpp是一个优秀的C++数值计算库,它提供了类似Python NumPy的功能,让C++开发者能够高效地进行科学计算和数据处理。本文将全面介绍NumCpp的核心功能和使用方法。
一、基础容器与数组操作
NumCpp的核心数据结构是NdArray
,它是一个N维数组容器,类似于NumPy的ndarray。我们可以通过多种方式创建和操作这些数组:
// 直接初始化二维数组
nc::NdArray<int> a0 = { {1, 2}, {3, 4} };
// 改变数组形状
nc::NdArray<int> a1 = { {1, 2}, {3, 4}, {5, 6} };
a1.reshape(2, 3); // 将3x2数组变为2x3
// 类型转换
auto a2 = a1.astype<double>();
二、数组初始化方法
NumCpp提供了多种数组初始化方式,满足不同场景需求:
// 线性空间数组
auto a3 = nc::linspace<int>(1, 10, 5); // 1到10之间等距5个数
// 范围数组
auto a4 = nc::arange<int>(3, 7); // [3,4,5,6]
// 特殊矩阵
auto a5 = nc::eye<int>(4); // 4x4单位矩阵
auto a6 = nc::zeros<int>(3, 4); // 3x4零矩阵
auto a8 = nc::ones<int>(3, 4); // 3x4全1矩阵
auto a10 = nc::nans(3, 4); // 3x4 NaN矩阵
auto a12 = nc::empty<int>(3, 4); // 未初始化的3x4矩阵
三、数组切片与索引
NumCpp支持强大的切片和索引功能:
auto a14 = nc::random::randInt<int>({10, 10}, 0, 100);
// 单个元素访问
auto value = a14(2, 3);
// 切片操作
auto slice = a14({2, 5}, {2, 5}); // 行2-5,列2-5的子矩阵
auto rowSlice = a14(a14.rSlice(), 7); // 所有行的第7列
// 布尔索引
auto values = a14[a14 > 50]; // 获取大于50的所有元素
a14.putMask(a14 > 50, 666); // 将大于50的元素替换为666
四、随机数生成
NumCpp内置了多种随机数生成器:
nc::random::seed(666); // 设置随机种子
auto a15 = nc::random::randN<double>({3, 4}); // 标准正态分布
auto a16 = nc::random::randInt<int>({3, 4}, 0, 10); // 均匀整数分布
auto a17 = nc::random::rand<double>({3, 4}); // [0,1)均匀分布
auto a18 = nc::random::choice(a17, 3); // 从a17中随机选择3个元素
五、数组拼接与组合
NumCpp提供了多种数组拼接方式:
auto a = nc::random::randInt<int>({3, 4}, 0, 10);
auto b = nc::random::randInt<int>({3, 4}, 0, 10);
auto c = nc::random::randInt<int>({3, 4}, 0, 10);
auto a19 = nc::stack({a, b, c}, nc::Axis::ROW); // 沿行方向堆叠
auto a20 = nc::vstack({a, b, c}); // 垂直堆叠
auto a21 = nc::hstack({a, b, c}); // 水平堆叠
auto a22 = nc::append(a, b, nc::Axis::COL); // 沿列方向追加
六、矩阵操作
NumCpp支持多种矩阵操作:
auto d = nc::random::randInt<int>({5, 5}, 0, 10);
auto a23 = nc::diagonal(d); // 获取对角线元素
auto a24 = nc::triu(a); // 上三角矩阵
auto a25 = nc::tril(a); // 下三角矩阵
auto a26 = nc::flip(d, nc::Axis::ROW); // 按行翻转
auto a27 = nc::flipud(d); // 上下翻转
auto a28 = nc::fliplr(d); // 左右翻转
七、数学运算
NumCpp支持丰富的数学运算:
// 基本运算
auto a52 = nc::abs(a); // 绝对值
auto a53 = nc::sign(a); // 符号函数
auto a54 = nc::remainder(a, b); // 余数
auto a55 = nc::clip(a, 3, 8); // 限制在[3,8]范围内
// 插值运算
auto xp = nc::linspace<double>(0.0, 2.0 * nc::constants::pi, 100);
auto fp = nc::sin(xp);
auto x = nc::linspace<double>(0.0, 2.0 * nc::constants::pi, 1000);
auto f = nc::interp(x, xp, fp); // 线性插值
// 指数和对数
auto a56 = nc::exp(a); // 指数
auto a57 = nc::expm1(a); // exp(x)-1
auto a58 = nc::log(a); // 自然对数
auto a59 = nc::log1p(a); // log(1+x)
// 幂运算
auto a60 = nc::power<int>(a, 4); // 四次方
auto a61 = nc::sqrt(a); // 平方根
auto a62 = nc::square(a); // 平方
auto a63 = nc::cbrt(a); // 立方根
八、线性代数
NumCpp提供了完整的线性代数支持:
auto a71 = nc::norm<int>(a); // 矩阵范数
auto a72 = nc::dot<int>(a, b.transpose()); // 矩阵乘法
auto a73 = nc::random::randInt<int>({3, 3}, 0, 10);
auto a74 = nc::random::randInt<int>({4, 3}, 0, 10);
auto a75 = nc::random::randInt<int>({1, 4}, 0, 10);
auto value9 = nc::linalg::det(a73); // 行列式
auto a76 = nc::linalg::inv(a73); // 矩阵求逆
auto a77 = nc::linalg::lstsq(a74, a75); // 最小二乘解
auto a78 = nc::linalg::matrix_power<int>(a73, 3); // 矩阵幂
auto a79 = nc::linalg::multi_dot<int>({a, b.transpose(), c}); // 链式矩阵乘法
// SVD分解
nc::NdArray<double> u, s, vt;
nc::linalg::svd(a.astype<double>(), u, s, vt);
九、文件I/O操作
NumCpp支持将数组保存到文件和从文件加载:
// 打印数组
a.print();
std::cout << a << std::endl;
// 文本文件操作
auto tempDir = std::filesystem::temp_directory_path();
auto tempTxt = (tempDir / "temp.txt").string();
a.tofile(tempTxt, '\n'); // 保存到文本文件
auto a50 = nc::fromfile<int>(tempTxt, '\n'); // 从文本文件加载
// 二进制文件操作
auto tempBin = (tempDir / "temp.bin").string();
nc::dump(a, tempBin); // 保存到二进制文件
auto a51 = nc::load<int>(tempBin); // 从二进制文件加载
十、总结
NumCpp为C++开发者提供了强大的数值计算能力,其API设计借鉴了NumPy,使得熟悉Python科学计算的开发者能够快速上手。本文介绍了NumCpp的主要功能,包括:
- 多维数组的创建和操作
- 各种初始化方法
- 强大的切片和索引功能
- 随机数生成
- 数组拼接和组合
- 矩阵操作
- 丰富的数学函数
- 线性代数运算
- 文件I/O操作
NumCpp是C++中进行科学计算和数据分析的优秀工具,特别适合需要在C++环境中实现高性能数值计算的场景。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考