Python NumPy 使用指南:科学计算的基石
Python NumPy 使用指南科学计算的基石作者书到用时方恨少发布日期2026年4月3日阅读时长约22分钟 前言在 Python 数据科学和数值计算的生态系统中NumPyNumerical Python就像一座坚实的地基。它提供了高性能的多维数组对象ndarray以及丰富的数学函数库是 Pandas、SciPy、Matplotlib、scikit-learn 等顶级库的底层支柱。如果说 Python 本身是瑞士军刀那么 NumPy 就是为你提供了一把削铁如泥的战术刀——尤其是在处理大规模数值数据时它的向量化操作可以比原生 Python 循环快几十倍甚至上百倍。无论你是从事数据分析、机器学习、物理模拟还是图像处理掌握 NumPy 都将是你迈向高效科学计算的必经之路。本篇博客将从零开始带你系统学习 NumPy 的核心概念、数组操作、数学函数、广播机制、线性代数、随机数生成以及最佳实践。让我们一起揭开数值计算的神秘面纱1. NumPy 是什么为什么需要它1.1 从 Python 列表到 NumPy 数组Python 自带的列表可以存储任意类型灵活性很高但代价是性能低下。每个元素都是完整的 Python 对象包含引用计数、类型信息等额外开销并且在迭代操作时逐元素进行类型检查极其低效。# 原生 Python 列表实现向量加法a[1,2,3,4]b[5,6,7,8]c[a[i]b[i]foriinrange(len(a))]# 慢且不优雅NumPy 数组存储的是同质数据如全部为 int64 或 float32数据在内存中连续排列并利用底层 C 和 Fortran 库进行向量化计算性能飞跃。1.2 核心优势高性能向量化运算对整个数组进行操作无需显式循环。内存效率紧凑的内存布局节省空间。丰富的数学函数线性代数、傅里叶变换、随机数、统计等。广播机制对不同形状的数组进行智能计算。与其他语言集成C/C/Fortran 扩展容易是许多高性能库的桥梁。一句话总结如果你在 Python 中处理数值数据NumPy 几乎总是你的第一选择。2. 快速入门创建 NumPy 数组2.1 安装与导入pipinstallnumpyimportnumpyasnp# 惯例别名2.2 创建数组的多种方式# 从列表创建arr1np.array([1,2,3,4,5])arr2np.array([[1,2],[3,4]])# 预分配数组zerosnp.zeros((3,4))# 全0形状3x4onesnp.ones((2,3))# 全1emptynp.empty((2,2))# 未初始化随机值fullnp.full((2,3),7)# 填充指定值eyenp.eye(4)# 单位矩阵# 序列生成arangenp.arange(0,10,2)# [0, 2, 4, 6, 8]linspacenp.linspace(0,1,5)# [0., 0.25, 0.5, 0.75, 1.]# 随机数组randnp.random.rand(3,4)# [0,1)均匀分布randnnp.random.randn(2,3)# 标准正态分布randintnp.random.randint(0,10,size(2,3))# 随机整数# 形状转换arrnp.arange(12)reshapedarr.reshape(3,4)# 变成3行4列2.3 数组属性arrnp.array([[1,2,3],[4,5,6]])print(arr.shape)# (2, 3) 维度元组print(arr.ndim)# 2 维数print(arr.size)# 6 元素总数print(arr.dtype)# int64或 int32取决于平台print(arr.itemsize)# 8 每个元素字节数print(arr.nbytes)# 48 总字节数3. 索引、切片与花式索引NumPy 的索引语法与 Python 列表类似但更强大。3.1 基本索引与切片arrnp.arange(10)print(arr[2])# 2print(arr[2:7])# [2 3 4 5 6]print(arr[2:7:2])# [2 4 6]# 二维数组arr2dnp.array([[1,2,3],[4,5,6],[7,8,9]])print(arr2d[0,2])# 3print(arr2d[1:3,0:2])# [[4 5], [7 8]]注意数组切片返回的是视图view而不是副本。修改视图会影响原数组。若要副本显式使用.copy()。3.2 花式索引整数数组索引arrnp.arange(10)*10indices[1,3,5]print(arr[indices])# [10 30 50]arr2dnp.arange(12).reshape(3,4)row_indices[0,2]col_indices[1,3]print(arr2d[row_indices,col_indices])# [1, 11] (0,1) 和 (2,3) 元素3.3 布尔索引arrnp.random.randn(5)maskarr0print(arr[mask])# 只保留正值# 直接使用条件print(arr[arr0])# 二维示例arr2dnp.array([[1,2],[3,4],[5,6]])print(arr2d[arr2d[:,1]3])# 第二列大于3的行4. ⚡ 向量化运算与通用函数ufunc4.1 数组算术运算anp.array([1,2,3])bnp.array([4,5,6])print(ab)# [5 7 9]print(a*b)# [4 10 18] 元素乘法print(a**2)# [1 4 9]print(np.sqrt(a))# [1. 1.414 1.732]# 与标量运算print(a10)# [11 12 13]print(a*2)# [2 4 6]4.2 通用函数ufuncNumPy 提供了大量向量化函数它们比循环快几十倍。# 数学函数np.sin(arr),np.cos(arr),np.exp(arr),np.log(arr),np.abs(arr)# 比较函数np.greater(a,b),np.equal(a,b),np.maximum(a,b)# 聚合函数arrnp.array([1,2,3,4])print(arr.sum())# 10print(arr.mean())# 2.5print(arr.std())# 标准差print(arr.min(),arr.max())# 1, 4print(arr.argmax())# 3 (最大值的索引)# 指定轴方向arr2dnp.array([[1,2],[3,4]])print(arr2d.sum(axis0))# 按列求和 - [4, 6]print(arr2d.sum(axis1))# 按行求和 - [3, 7]性能对比对一个长度为 1000 万的数组求正弦NumPy 向量化比 Python 循环快约 50 倍。5. 广播机制Broadcasting广播允许不同形状的数组进行算术运算无需手动复制数据。5.1 广播规则从尾部维度开始比较两个数组的维度要么相等要么其中一个为 1要么缺失。# 示例1数组 标量arrnp.arange(3)# shape (3,)print(arr10)# 10 广播到 (3,)# 示例2列向量 行向量colnp.arange(3).reshape(3,1)# (3, 1)rownp.arange(4).reshape(1,4)# (1, 4)resultcolrow# (3, 4)print(result)5.2 实用技巧# 标准化每一列减去均值除以标准差datanp.random.randn(5,3)meandata.mean(axis0)# shape (3,)stddata.std(axis0)# shape (3,)normalized(data-mean)/std# 广播生效常见错误形状不兼容时会抛出ValueError: operands could not be broadcast together。6. 形状操作与数组重塑6.1 改变形状arrnp.arange(12)print(arr.reshape(3,4))# 返回新视图print(arr.reshape(2,-1))# -1 自动推断变成 (2,6)print(arr.ravel())# 展平为 1D视图print(arr.flatten())# 展平为 1D副本# 转置arr2dnp.array([[1,2,3],[4,5,6]])print(arr2d.T)# 转置6.2 合并与拆分# 合并anp.array([[1,2],[3,4]])bnp.array([[5,6]])# 垂直堆叠np.vstack((a,b))# [[1,2],[3,4],[5,6]]# 水平堆叠cnp.array([[7],[8]])np.hstack((a,c))# [[1,2,7],[3,4,8]]# 更通用的 concatenatenp.concatenate((a,b),axis0)# 拆分arrnp.arange(12).reshape(3,4)upper,lowernp.vsplit(arr,2)# 分成两块 (2,4) 和 (1,4)left,rightnp.hsplit(arr,2)# 分成 (3,2) 和 (3,2)7. 线性代数与矩阵运算NumPy 的linalg模块提供了线性代数核心功能。# 矩阵乘法anp.array([[1,2],[3,4]])bnp.array([[5,6],[7,8]])print(np.dot(a,b))# 或 a bprint(a b)# Python 3.5 推荐的矩阵乘法# 其他运算invnp.linalg.inv(a)# 逆矩阵detnp.linalg.det(a)# 行列式eigvals,eigvecsnp.linalg.eig(a)# 特征值和特征向量solvenp.linalg.solve(A,b)# 解线性方程组 Ax b# 常见分解U,s,Vtnp.linalg.svd(a)# 奇异值分解q,rnp.linalg.qr(a)# QR 分解8. 随机数生成np.random模块是科学模拟和机器学习的核心工具。# 设置随机种子保证可重复性np.random.seed(42)# 分布uniformnp.random.uniform(0,1,100)# 均匀分布normalnp.random.normal(0,1,100)# 正态分布poissonnp.random.poisson(5,100)# 泊松分布# 随机整数randintnp.random.randint(0,10,size(3,4))# 随机排列arrnp.arange(10)np.random.shuffle(arr)# 原地打乱permnp.random.permutation(10)# 返回新打乱数组# 随机选择np.random.choice(5,size3,replaceFalse,p[0.1,0.2,0.3,0.2,0.2])注意自 NumPy 1.17 起推荐使用新的default_rng系统更现代化且可分离。rngnp.random.default_rng(seed42)rng.normal(0,1,100)9. 文件输入输出9.1 二进制格式.npy / .npzarrnp.arange(100)np.save(my_array.npy,arr)# 保存loadednp.load(my_array.npy)# 加载# 保存多个数组np.savez(archive.npz,aarr1,barr2)datanp.load(archive.npz)print(data[a])9.2 文本格式CSV、TXTarrnp.random.randn(5,3)np.savetxt(data.csv,arr,delimiter,,headerx,y,z,comments)loadednp.loadtxt(data.csv,delimiter,,skiprows1)# 或用 genfromtxt 处理缺失值loaded2np.genfromtxt(data.csv,delimiter,,skip_header1,filling_values0)10. 实战案例案例一图像灰度化与亮度调整importnumpyasnpfromPILimportImage# 假设有一张彩色图像宽高 H, W, 3imgnp.array(Image.open(photo.jpg))# shape (H, W, 3), dtypeuint8# 灰度化公式Y 0.299R 0.587G 0.114Bgraynp.dot(img[...,:3],[0.299,0.587,0.114]).astype(np.uint8)# 提高亮度 30%brightenednp.clip(gray*1.3,0,255).astype(np.uint8)Image.fromarray(brightened).save(bright.jpg)案例二欧几里得距离矩阵计算# 计算点集 points 中每对点之间的距离pointsnp.random.randn(1000,3)# 1000个三维点# 方法1双重循环慢# 方法2向量化快diffpoints[:,np.newaxis,:]-points[np.newaxis,:,:]# (1000,1000,3)distnp.sqrt(np.sum(diff**2,axis-1))print(dist.shape)# (1000, 1000)案例三数据标准化与 PCA 降维# 标准化defstandardize(X):meanX.mean(axis0)stdX.std(axis0)return(X-mean)/std# 简单 PCA保留前 k 个主成分defpca(X,k):X_centeredX-X.mean(axis0)covnp.cov(X_centered,rowvarFalse)eig_vals,eig_vecsnp.linalg.eigh(cov)idxnp.argsort(eig_vals)[::-1][:k]componentseig_vecs[:,idx]returnX_centered components datanp.random.randn(500,20)reducedpca(data,2)print(reduced.shape)# (500, 2)11. ⚠️ 常见陷阱与注意事项11.1 副本 vs 视图切片通常返回视图修改视图会影响原数组。若需独立副本务必使用.copy()。arrnp.arange(10)subarr[::2]# 视图sub[0]999print(arr)# [999, 1, 2, ...] 被修改了11.2 整形与内存布局reshape在可能的情况下返回视图但有时返回副本如非连续数组。使用np.may_share_memory检测。11.3 浮点数精度问题print(0.10.20.3)# False# 使用 np.isclose 比较np.isclose(0.10.2,0.3)# True11.4 广播的副作用不注意形状会导致意外的高维扩展消耗大量内存。例如arr[:, np.newaxis] - arr会生成巨大的中间数组。11.5 不要混用 Python 列表操作arrnp.array([1,2,3])arr.append(4)# AttributeError NumPy 数组没有 appendnp.append(arr,4)# 返回新数组效率低尽量避免频繁使用11.6 内存占用大数组操作时注意中间结果的内存占用。可使用out参数或原地操作减少复制。# 原地操作np.add(arr1,arr2,outarr1)12. NumPy vs Pandas vs 原生 Python特性NumPyPandas原生 Python 列表数据类型同质数值为主异质带标签异质性能数值计算极高向量化高底层 NumPy低缺失值处理有限需掩码强大NaN无索引功能整数/布尔/花式索引标签索引、层次化索引整数索引适用场景数值算法、图像、模拟数据分析、表格处理通用编程选型建议纯数值计算、大型矩阵运算 →NumPy带标签的表格数据、缺失值、时间序列 →Pandas简单、少量数据或异质混合类型 →原生列表13. 总结通过本文我们全面学习了 NumPy 的核心知识✅数组创建多种方式生成ndarray✅索引切片基本、花式、布尔索引✅向量化运算ufunc 带来的性能飞跃✅广播机制不同形状数组的智能计算✅形状操作重塑、合并、拆分、转置✅线性代数矩阵乘法、分解、求解方程组✅随机数生成各种分布数据✅文件 I/O二进制和文本格式的保存加载✅实战案例图像处理、距离矩阵、PCA✅注意事项视图/副本、精度、内存NumPy 是 Python 科学计算的基石熟练掌握它将为你打开数据科学和机器学习的大门。学 NumPy 最好的方式就是多写代码尝试用向量化操作替代所有显式循环。希望这篇指南能够帮助你在数值计算的海洋中扬帆起航。如果你在实践中遇到了有趣的挑战或独特的优化技巧欢迎在评论区分享感谢阅读我们下一篇博客见
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2480158.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!