目录

一、先搞懂:NumPy是什么?

二、核心重点:NumPy 核心功能详解

2.1 NumPy数组(ndarray)创建

2.2 NumPy数组索引(取值/切片)

2.3 重点难点:NumPy广播机制详解

2.3.1  广播的核心规则(必记)

2.3.2  常见广播示例(结合代码理解)

一维数组的广播

二维数组的广播

三维数组的广播

2.3.3  标量与数组的广播(最常用)

2.3.4  广播失败的场景

2.4 NumPy线性代数运算

三、总结:初学者必掌握的核心要点


前言:

        NumPy是Python数据分析和AI学习的基础库,核心优势是高效处理多维数组(ndarray)。本文针对初学者,梳理NumPy核心基础:数组创建、索引、广播机制(重点)、线性代数运算,全程搭配简洁代码示例,帮你快速上手实操。

一、先搞懂:NumPy是什么?

        NumPy(Numerical Python)是Python的数值计算库,专门解决数组运算问题。相比Python原生列表,它的优势在于:

  • 存储更高效,占用内存少

  • 运算速度快(底层C语言实现,避开Python解释器开销)

  • 支持多维数组和广播、线性代数等高级运算

安装(已安装可跳过):

# 命令行安装
pip install numpy

# 安装验证(若安装成功,将返回已安装的版本号)
python -c "import numpy; print(numpy.__version__)"

# 使用时导入库(简写为np)
import numpy as np

二、核心重点:NumPy 核心功能详解

2.1 NumPy数组(ndarray)创建

        NumPy的核心是ndarray对象,常用创建方法有3种,直接上代码+说明:

import numpy as np
 
# 1. 从Python列表或元组转换(最常用)
List1 = [1,2,3,4]
arr1 = np.array(List1)  # 一维数组
print("一维数组:\n", arr1)  # 输出:[1 2 3 4]

List2 = [[1,2],[3,4]]
arr2 = np.array(List2)  # 二维数组(矩阵)
print("二维数组:\n", arr2)  # 输出:[[1 2],[3 4]]

# 2. 快速创建特殊数组(避免手动写列表)
arr_zeros = np.zeros((2,3))  # 2行3列的全0数组
arr_ones = np.ones((3,2))   # 3行2列的全1数组
arr_full = np.full((2,2), 5)# 2行2列的全5数组
arr_range = np.arange(1,10,2)# 从1到9,步长2:[1 3 5 7 9]
arr_lin = np.linspace(0,1,5)# 0到1之间均匀取5个数:[0.  0.25 0.5  0.75 1.  ]

# 3. 创建随机数组
arr_rand = np.random.rand(2,2)  # 0-1之间的2行2列随机数
arr_randn = np.random.randn(2,2) # 符合正态分布的2行2列随机数

# 小贴士:可以使用shape属性查看数组维度(行×列),dtype查看数据类型。
# 例:print(arr2.shape) → (2,2),print(arr2.dtype) → int64

2.2 NumPy数组索引(取值/切片)

        索引就是从数组中获取元素,和Python列表类似,但支持多维索引,重点看二维数组(矩阵)的操作:

import numpy as np

# 先创建一个示例二维数组
arr = np.array([[1,2,3],[4,5,6],[7,8,9]])
print("原始数组:\n", arr)

# 1. 一维数组索引(和列表完全一致)
arr1 = np.array([10,20,30])
print("一维数组第2个元素:", arr1[1])  # 索引从0开始,输出20
print("一维数组切片(1到末尾):", arr1[1:])  # 输出[20 30]

# 2. 二维数组索引(行索引, 列索引)
print("第2行第3列元素:", arr[1,2])  # 输出6(第2行索引1,第3列索引2)
print("第1行所有元素:", arr[0,:])   # 输出[1 2 3](:表示取所有列)
print("第3列所有元素:", arr[:,2])   # 输出[3 6 9](:表示取所有行)

# 3. 二维数组切片(范围取值)
print("前2行,前2列元素:\n", arr[:2,:2])  # 输出[[1 2],[4 5]]
print("第2-3行,第1-2列元素:\n", arr[1:3,0:2])  # 输出[[4 5],[7 8]]

# 4. 布尔索引(条件筛选,实用!)
print("数组中大于5的元素:", arr[arr>5])  # 输出[6 7 8 9]

# 5. 混用
result = arr[1:3,0:2][arr[1:3,0:2] > 5]
print("第2-3行,第1-2列元素中大于5的元素:", result)

2.3 重点难点:NumPy广播机制详解

        广播是NumPy最强大的特性之一,简单说:当两个数组形状不同时,NumPy会自动调整它们的形状,使其可以进行元素级运算(如加减乘除),不用手动扩展数组,极大简化代码。

2.3.1  广播的核心规则(必记)

  • 维度补1:先比较两个数组的维度,维度少的数组,在前面补1(比如二维数组(2,3)和三维数组(4,2,3)比较时,二维数组补成(1,2,3))

  • 逐维兼容:对于补维后的两个数组,逐维度比较形状:要么维度大小相等,要么其中一个为1;只要有一个维度不满足,就会报错即广播失败

  • 逻辑扩展:满足规则后,运算时将形状为1的维度,扩展成和另一个数组相同的大小(仅逻辑扩展,不占用实际内存,所以高效)

一言以蔽之:先补维度,再看维度是否兼容,兼容就扩展维度为1的轴,最后逐元素运算。

2.3.2  常见广播示例(结合代码理解)

  • 一维数组的广播

示例代码:

import numpy as np

# 定义一个数组(形状为(4, 3))
arr1 = np.sort(np.array([0,1,2,3]*3)).reshape(4,3)

# 定义第二个数组(形状为(1, 3),对应一维数组在轴0上的广播)
arr2 = np.array([[1, 2, 3]])

# 直接相加(NumPy自动广播arr2到(4, 3)形状)
result = arr1 + arr2

print("第一个数组:")
print(arr1)
print("\n第二个数组:")
print(arr2)
print("\n广播相加的结果:")
print(result)

运行结果如下:

第一个数组:
[[0 0 0]
 [1 1 1]
 [2 2 2]
 [3 3 3]]

第二个数组:
[[1 2 3]]

广播相加的结果:
[[1 2 3]
 [2 3 4]
 [3 4 5]
 [4 5 6]]

分析底层逻辑:

  1. 补维度:arr1形状 (4,3),arr2形状 (1,3)(维度数相同,无需补 1);

  2. 逐维兼容:轴0(4 vs 1)兼容,轴1(3 vs 3)兼容;

  3. 逻辑扩展:arr2的轴 0(大小 1)扩展为4(虚拟复制 4 行),变成和arr1一样的 (4,3);

  4. 通俗总结:当两个数组 “列数一样、行数不一样(其中一个行数为1)” 时,NumPy会自动把 “行数为1的数组” 复制多份,补成和另一个数组一样的行数,然后再计算。

  • 二维数组的广播

示例代码:

import numpy as np

# 定义第一个数组(形状(4,3),对应图中左侧数组)
arr1 = np.sort(np.array([0,1,2,3]*3)).reshape(4,3)

# 定义第二个数组(形状(4,1),对应图中中间的二维数组)
arr2 = np.array([
    [1],
    [2],
    [3],
    [4]
])

# 广播相加(NumPy自动扩展arr2的列维度)
result = arr1 + arr2

print("数组1(4行3列):")
print(arr1)
print("\n数组2(4行1列):")
print(arr2)
print("\n广播相加结果(4行3列):")
print(result)

运行结果:

数组1(4行3列):
[[0 0 0]
 [1 1 1]
 [2 2 2]
 [3 3 3]]

数组2(4行1列):
[[1]
 [2]
 [3]
 [4]]

广播相加结果(4行3列):
[[1 1 1]
 [3 3 3]
 [5 5 5]
 [7 7 7]]

分析底层逻辑:

  1. 补维度:arr1形状 (4,3),arr2形状 (4,1)(维度数相同,无需补 1);

  2. 逐维兼容:轴0(4 vs 4)兼容,轴1(3 vs 1)兼容;

  3. 逻辑扩展:arr2的轴1(大小 1)扩展为3(虚拟复制3列),变成和arr1一样的 (4,3);

  4. 通俗总结:当数组 “行数相同、列数不同(其中一个列数为1)” 时,NumPy会自动把 “列数为1的数组” 的列复制多份,补成和另一个数组一样的列数,再计算。

  • 三维数组的广播

示例代码

import numpy as np

# 定义三维数组arr1(形状(3,4,2),对应图中左侧数组)
# 结构:3个"层",每个层是4行2列的二维数组
arr1 = np.array([0,1,2,3,4,5,6,7]*3).reshape(3,4,2)

# 定义待广播的数组arr2(形状(4,2),对应图中中间数组)
arr2 = np.array([0,1,2,3,4,5,6,7]).reshape(4,2)

# 三维广播相加
arr3 = arr1 + arr2

# 打印结果验证
print("arr1的形状:", arr1.shape)
print("arr1的内容:\n",arr1)
print("\narr2的形状:", arr2.shape)
print("arr2的内容:\n",arr2)
print("\n广播相加后arr3的形状:", arr3.shape)
print("arr3的内容:\n",arr3)

运行结果:

arr1的形状: (3, 4, 2)
arr1的内容:
 [[[0 1]
  [2 3]
  [4 5]
  [6 7]]

 [[0 1]
  [2 3]
  [4 5]
  [6 7]]

 [[0 1]
  [2 3]
  [4 5]
  [6 7]]]

arr2的形状: (4, 2)
arr2的内容:
 [[0 1]
 [2 3]
 [4 5]
 [6 7]]

广播相加后arr3的形状: (3, 4, 2)
arr3的内容:
 [[[ 0  2]
  [ 4  6]
  [ 8 10]
  [12 14]]

 [[ 0  2]
  [ 4  6]
  [ 8 10]
  [12 14]]

 [[ 0  2]
  [ 4  6]
  [ 8 10]
  [12 14]]]

分析底层逻辑:

  1. 补维度:arr1形状 (3,4,2)(3维),arr2形状 (4,2)(2维)→ 给arr2左侧补1,变成 (1,4,2);

  2. 逐维兼容:轴0(3 vs 1)兼容,轴1(4 vs 4)兼容,轴2(2 vs 2)兼容;

  3. 逻辑扩展:arr2的轴0(大小 1)扩展为3(虚拟复制 3 层),变成和arr1一样的 (3,4,2);

  4. 通俗总结:三维数组的 “层维度”(轴0)如果不匹配(其中一个层数为1),NumPy会自动把 “层数为1的数组” 的层复制多份,补成和另一个数组一样的层数,再计算。

2.3.3  标量与数组的广播(最常用)

        标量即 “单个数值”(比如510.2-3),和数组相对。在NumPy中,标量没有 “维度” 或 “形状” 的概念,可看作 “形状为 () 的空维度对象”。

        标量与数组的广播,就是NumPy自动把单个数值 “变形成” 和数组一模一样的形状,然后给数组每个元素都做相同的运算,既简洁又高效。

示例1:一维数组+标量

arr1 = np.array([1, 2, 3])  # 形状(3,),一维数组(1行3列)
scalar = 10                 # 标量
result1 = arr1 + scalar
print("一维数组+标量结果:", result1)

# 输出:一维数组+标量结果: [11 12 13]

示例2:二维数组 + 标量(更常用)

arr2 = np.array([[1, 2], [3, 4]])  # 形状(2,2),二维数组(2行2列)
result2 = arr2 * 2                 # 标量2,乘法运算
print("\n二维数组×标量结果:\n", result2)
# 输出:
# [[2 4]
#  [6 8]]

实例3:三维数组 + 标量(同理)

arr3 = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])  # 形状(2,2,2)
result3 = arr3 - 1                                      # 标量1,减法运算
print("\n三维数组-标量结果:\n", result3)
# 输出:
# [[[0 1]
#   [2 3]]
#  [[4 5]
#   [6 7]]]

标量广播仅适用于元素级运算(+、-、×、/、//、% 等),不适用于矩阵乘法(矩阵乘法需要二维数组,标量无法参与)。

2.3.4  广播失败的场景

示例代码:

# 数组1:2行2列
arr1 = np.array([[1,2],[3,4]])
# 数组2:1行3列
arr2 = np.array([[1,2,3]])

# 尝试广播相加
try:
    result = arr1 + arr2
except ValueError as e:
    print("广播失败原因:", e)

运行结果:

广播失败原因: operands could not be broadcast together with shapes (2,2) (1,3)

分析失败逻辑:

  1. 补维度:arr1(2,2),arr2(1,3)(维度数相同,无需补1);

  2. 逐维兼容:轴0(2 vs 1)兼容,但轴1(2 vs 3)既不相等、也没有一个为1 → 不兼容,广播失败;

  3. 通俗总结:不是所有 “行数 / 列数不一样” 都能广播,必须满足「其中一个维度为1」,否则直接报错。

2.4 NumPy线性代数运算

        在AI学习中经常用到矩阵乘法、求逆、行列式等线性代数操作,NumPy的linalg模块提供了完整支持,下面使用实例代码介绍常用操作:

import numpy as np
from numpy.linalg import inv, det, eig  # 导入常用线性代数函数

# 1. 矩阵乘法(注意:不是元素级乘法,用@或dot())
A = np.array([[1,2],[3,4]])  # 2×2矩阵
B = np.array([[5,6],[7,8]])  # 2×2矩阵
# 方法1:用@符号(Python 3.5+支持,推荐)
mat_mul1 = A @ B
# 方法2:用dot()函数
mat_mul2 = A.dot(B)
print("矩阵乘法结果:\n", mat_mul1)
# 输出:[[19 22],[43 50]](计算规则:行×列求和)

# 2. 求矩阵的逆(仅方阵且可逆时可用)
A_inv = inv(A)
print("A的逆矩阵:\n", A_inv)
# 验证:A × A逆 = 单位矩阵(对角线为1,其他为0)
print("A×A逆验证:\n", A @ A_inv)

# 3. 求矩阵的行列式(仅方阵)
A_det = det(A)
print("A的行列式:", A_det)  # 输出-2.0

# 4. 求特征值和特征向量(AI中PCA、神经网络常用)
eigenvalues, eigenvectors = eig(A)
print("A的特征值:", eigenvalues)
print("A的特征向量:\n", eigenvectors)

# 5. 其他常用操作
C = np.array([[1,2,3],[4,5,6]])  # 2×3矩阵
print("矩阵转置:\n", C.T)  # 转置(行变列,列变行),输出3×2矩阵
print("矩阵的秩:", np.linalg.matrix_rank(C))  # 输出2

三、总结:初学者必掌握的核心要点

  1. 数组创建:重点掌握np.array()、np.zeros()、np.ones()、np.arange()、np.random.rand(),满足日常开发需求

  2. 数组索引:二维数组的“行,列”索引和切片是基础,布尔索引是实用技巧

  3. 广播机制:记住3个核心规则,多练示例,避免手动扩展数组的冗余操作

  4. 线性代数:区分“矩阵乘法(@)”和“元素级乘法(*)”,掌握逆、行列式、特征值的基本用法

建议:把文中代码逐行复制到Python环境中运行,修改参数观察结果(比如改数组形状、换运算符号),比单纯看文字理解更快。如果遇到问题,欢迎在评论区交流~

参考资料:NumPy官方文档(https://numpy.org/doc/stable/

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐