说到Python科学计算和深度学习,有一个库是怎么也绕不开的——NumPy。它就像一个性能极佳的“数学引擎”,专门为数组运算而生。
严格来说,NumPy是一个专注于数组计算的数学库,它的特点就是——快。它内部有一个叫ND array(N维数组)的核心数据结构,所有操作都围绕它展开。这个数组有个硬性要求:里面的数据类型必须统一。但也正因为这个“不近人情”的规定,再加上底层用C语言实现,NumPy在进行大规模数学运算时,速度能甩开纯Python好几条街。此外,它还贴心内置了很多实用的数学函数,比如求平均值、标准差等,简直是数据处理的瑞士军刀。
你可能会好奇,为什么深度学习领域总能看到NumPy的影子?
原因主要有两点。第一,深度学习模型动辄处理海量数据,比如图像、音频和文本。这些数据本质上就是数组或矩阵——一张图片就是一个三维数组(长、宽、颜色通道),一段音频就是二维数组(时间、振幅)。NumPy的ndarray就像一个超大容量的“数据容器”,不仅能轻松装下这些数据,还能让你像切蛋糕一样,用“切片”、“索引”等操作方便地获取和修改数据的局部信息。
第二,NumPy的“兼容性”做得非常出色。现在主流的深度学习框架,像TensorFlow和PyTorch,它们背后或多或少都借鉴了NumPy的设计思想。虽然这些框架有自己的“张量”(Tensor)结构,但和NumPy数组之间的转换几乎是无缝的。这意味着你可以把NumPy作为数据预处理的起点,喂给深度学习模型,再拿结果回来用NumPy进行调试和分析。这种灵活性,让它几乎成了AI领域的“通用货币”。
初识NumPy数组

数组的简单创建
我们身边的数据,很多都是以数组形式存在的。以最常见的图片为例,我们看到的是一幅画面,但对计算机来说,它就是一个由像素点组成的三维数组——高度、宽度和颜色通道。学习NumPy数组的创建,其实就是学习如何用计算机的语言来描述这些现实世界的数据。

通过`array`函数创建数组(一维、二维、三维)
最直接的方法,就是用 np.array() 函数,直接把Python列表“喂”给它。你可以创建一维的向量、二维的矩阵,甚至更高维的张量。



NumPy数组的常用属性
创建一个数组后,我们得先学会“审视”它。NumPy为数组提供了几个非常实用的“体检”属性。


.shape:这个属性使用频率最高,告诉我们数组的形状,比如 (3, 4) 就代表一个3行4列的矩阵。.ndim:数组的维数,比如二维数组就是2。.astype:我们可以通过它来改变数组的数据类型,比如从整数转成浮点数。


还有一个概念必须得提——轴。你可以把“轴”简单理解成“维度”。对于一个二维数组来说,axis=0 通常代表沿着行的方向(垂直向下),axis=1 代表沿着列的方向(水平向右)。这个概念在你后续做数组拼接或统计计算时至关重要。


创建数组的其他方式


等间隔数组
有时候,我们需要创建一个等差数列。比如在画函数图像或测试算法时,你可能会需要一系列均匀分布的点。NumPy提供了两个得力助手。


这两个函数都只能创建一维数组,但思路截然不同:
np.arange():它就像Python内置的range()函数,你给它指定起点、终点和步长,它会按步长生成一维数组。np.linspace():它的策略不同,你只需要告诉它起点、终点和想要生成的元素个数,它会自动“平均分配”这些点。




全等数组
另一个常见场景是,需要创建一个全都是0、全都是1,或者全部是某个固定数值的数组。这在初始化权重或生成“占位”数据时很常用。


这三个兄弟,功能相似,用法一致:
np.zeros():生成一个全为0的数组。np.ones():生成一个全为1的数组。np.full():生成一个元素全部为你指定的某个值的数组。






NumPy数组操作


数组形变
很多时候,我们手里的数据形状不对,需要“整形”。NumPy在这方面非常灵活。


改变数组形状,本质上就是改变它的 .shape 属性。这个过程只要保证元素总数不变,就可以任意“折叠”或“展开”。
ndarray.reshape():最常用的方法,传入你想要的形状,比如 (2, 6)。ndarray.T:对数组进行“转置”,也就是把行和列互换。ndarray.ra vel():这是一个非常实用的方法,它能把任意高维数组“拉直”,变成一个一维数组。










数组拼接
把多个小数组“拼”成一个大数组,是数据整合的常用操作。
np.concatenate():最通用的拼接函数。你可以通过axis参数指定沿着哪个轴拼接,灵活性很高。np.hstack():“水平”拼接。对于二维数组来说,就是沿着axis=1(列的方向)拼,相当于往右边“加宽”。np.vstack():“垂直”拼接。沿着axis=0(行的方向)拼,相当于往下“加高”。需要注意的是,它拼接一维数组时,会把多个一维数组“堆叠”成一个二维数组。






















数组拆分
有合就有分,数组拆分是拼接的反向操作。
np.hsplit():水平拆分,把数组按列“切”成几块。np.vsplit():垂直拆分,把数组按行“切”成几块。




NumPy数组索引
在数组中定位和提取数据,这就是“索引”的活。NumPy的索引用法和Python列表非常相似,甚至更强大,支持“花式索引”和“布尔索引”。




NumPy数组运算
这才是NumPy真正大展拳脚的地方。得益于其“向量化”能力,你可以像操作单个数字一样,对整个数组进行高效运算。


基本运算
四则运算(+-*/)、求模(%)、取整(//)、乘方(**),直接对两个同型的数组进行操作,NumPy会自动进行“逐元素”运算。比较运算(==, !=, >, <等)也同样如此,结果会生成一个由布尔值组成的新数组。矩阵乘法有专门的 @ 运算符,非常直观。






常用运算函数
除了基本运算,NumPy内置了大量的数学函数,它们会对数组中的每个元素生效。
np.sqrt(arr):开平方根。np.square(arr):求平方,和arr ** 2效果一样。np.sin(arr), np.cos(arr):三角函数。np.exp(arr):计算 e 的各元素次幂。np.log(arr):以 e 为底的自然对数。


常用统计函数
统计函数和上面那些运算函数有个本质区别:运算函数是“一对一”地处理,结果形状和原数组一致;而统计函数是“多对一”地汇总,结果通常是一个数或一个降维后的数组。
ndarray.max(), .min():求最大/最小值。ndarray.mean():求平均值。ndarray.std():求标准差。ndarray.var():求方差。ndarray.sum():求和。ndarray.argmax(), .argmin():找到最大/最小值所在的索引位置。
这些函数的用法基本都一个套路,最关键的就是掌握 axis 参数。如果不指定 axis,默认就是对整个数组进行计算,返回一个标量。如果你指定了 axis=1,它就会沿着行的方向(对每一列)进行计算,结果会降一个维度。




