第十一章

NumPy 库

Python数据科学的核心基石

欢迎关注微信公众号

coder程 查令十街84号

目录

为什么要用 NumPy 库

NumPy(Numerical Python)是Python科学计算的核心库,提供了高性能的多维数组对象。

Python 列表 vs NumPy 数组

特性 Python 列表 NumPy 数组
存储方式 分散存储(存指针) 连续内存存储
元素类型 任意类型混合 同类型元素
运算速度 慢(循环逐个计算) 快(C语言底层优化)
向量化运算 不支持 原生支持
广播机制 不支持 支持
核心优势: NumPy数组的运算速度比Python列表快10~100倍,这是数据科学选择NumPy的根本原因。

NumPy 数组的创建

# 导入NumPy库
import numpy as np

# 1. 从列表创建数组
a = np.array([1, 2, 3, 4, 5])
# 2. 创建二维数组
b = np.array([[1, 2, 3], [4, 5, 6]])

# 3. 创建特殊数组
zeros = np.zeros((3, 4))        # 3行4列的零矩阵
ones = np.ones((2, 3))          # 2行3列的全1矩阵
eye = np.eye(4)                  # 4x4单位矩阵

# 4. 等差/等比数列
arange = np.arange(0, 10, 2)      # [0, 2, 4, 6, 8]
linspace = np.linspace(0, 1, 5)    # [0, 0.25, 0.5, 0.75, 1]
logspace = np.logspace(0, 2, 3)    # [1, 10, 100]

# 5. 随机数组
rand = np.random.rand(3, 3)       # 0~1均匀分布
randn = np.random.randn(3, 3)     # 标准正态分布
randint = np.random.randint(0, 10, (2, 2))  # 0~9随机整数

NumPy 数组的性质

数组属性

import numpy as np
arr = np.array([[1,2,3],[4,5,6]])

# 数组形状与维度
print(arr.shape)      # (2, 3)  - 形状
print(arr.ndim)       # 2       - 维度数
print(arr.size)       # 6       - 元素总数
print(arr.dtype)      # int64   - 数据类型

# 重塑数组
arr2 = arr.reshape(3, 2)
arr3 = arr.reshape(-1, 1)   # -1自动推断

数据类型

# 指定数据类型
arr_int = np.array([1,2,3], dtype=np.int32)
arr_float = np.array([1,2,3], dtype=np.float64)

# 类型转换
arr_f = arr.astype(np.float32)

# 常用dtype
# int8/16/32/64, uint8/16/32/64
# float16/32/64
# complex64/128
# bool, string_, object
注意: reshape() 返回新数组视图,不复制数据; -1 表示该维度大小由其他维度自动推断。

数组的索引与切片

import numpy as np
arr = np.array([[1,2,3,4],
                [5,6,7,8],
                [9,10,11,12]])

# 基础索引
print(arr[1, 2])       # 7  - 第2行第3列
print(arr[0])          # [1,2,3,4] - 第1行

# 切片
print(arr[1:3, 1:4])   # [[6,7,8],[10,11,12]]
print(arr[:, 2])       # [3,7,11] - 第3列
print(arr[::2])        # 每隔一行

# 布尔索引(筛选)
print(arr[arr > 5])    # [6,7,8,9,10,11,12]
print(arr[(arr > 3) & (arr < 10)])  # [4,5,6,7,8,9]

# 花式索引
print(arr[[0,2], [1,3]])  # [2, 12] - (0,1)和(2,3)

NumPy 四大运算 — 算术运算

基本算术

import numpy as np
a = np.array([1,2,3])
b = np.array([4,5,6])

# 元素级运算
print(a + b)      # [5, 7, 9]
print(a - b)      # [-3, -3, -3]
print(a * b)      # [4, 10, 18]
print(a / b)      # [0.25, 0.4, 0.5]
print(a ** 2)     # [1, 4, 9]

# 标量运算(广播)
print(a + 10)     # [11, 12, 13]
print(a * 2)      # [2, 4, 6]

通用函数(ufunc)

# 数学函数
np.sqrt(a)         # 平方根
np.exp(a)          # 指数 e^x
np.log(a)          # 自然对数
np.sin(a)          # 正弦
np.cos(a)          # 余弦

# 取整函数
np.floor([1.7,2.3])    # [1., 2.]
np.ceil([1.7,2.3])     # [2., 3.]
np.round([1.55], 1)    # [1.6]

# 绝对值
np.abs([-1, -2, 3])   # [1, 2, 3]

NumPy 四大运算 — 比较运算

import numpy as np
a = np.array([1, 2, 3, 4, 5])
b = np.array([5, 4, 3, 2, 1])

# 元素级比较,返回布尔数组
print(a == b)      # [False, False, True, False, False]
print(a != b)      # [True, True, False, True, True]
print(a > b)       # [False, False, False, True, True]
print(a <= b)      # [True, True, True, False, False]

# 数组整体比较
print(np.array_equal(a, b))   # False
print(np.allclose(a, b))    # False(浮点数近似相等)

# 逻辑运算(布尔数组之间)
cond1 = a > 2
cond2 = a < 5
print(np.logical_and(cond1, cond2))   # [False, False, True, True, False]
print(np.logical_or(cond1, cond2))    # [True, True, True, True, True]
print(np.logical_not(cond1))          # [True, True, False, False, False]

# 条件筛选:np.where
print(np.where(a > 3, "大", "小"))   # ['小', '小', '小', '大', '大']

NumPy 四大运算 — 聚合运算

基础聚合函数

import numpy as np
arr = np.array([[1,2,3],
                [4,5,6],
                [7,8,9]])

# 全局聚合
np.sum(arr)        # 45
np.mean(arr)       # 5.0
np.std(arr)        # 2.58... 标准差
np.var(arr)        # 6.66... 方差
np.min(arr)        # 1
np.max(arr)        # 9
np.prod(arr)       # 362880

# 对象方法方式
arr.sum()          # 45
arr.mean()         # 5.0
arr.max()          # 9

按轴聚合

# axis=0:沿着行方向(纵向),每列求和
np.sum(arr, axis=0)    # [12, 15, 18]

# axis=1:沿着列方向(横向),每行求和
np.sum(arr, axis=1)    # [6, 15, 24]

# 更复杂的聚合
np.argmax(arr)          # 8 - 最大值的索引
np.argmin(arr, axis=0)  # [0,0,0] - 每列最小值行索引

# 累积运算
np.cumsum(arr)          # [1,3,6,10,15,21,28,36,45]
np.cumprod(arr)         # [1,2,6,24,120,720,5040,40320,362880]
axis记忆法: axis=0 是「压扁行」,结果维度与列数一致; axis=1 是「压扁列」,结果维度与行数一致。

NumPy 四大运算 — 线性代数

import numpy as np
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])

# 矩阵乘法(点积)
print(A @ B)              # [[19,22],[43,50]]
print(np.dot(A, B))       # 同上

# 转置
print(A.T)                # [[1,3],[2,4]]

# 逆矩阵
A_inv = np.linalg.inv(A)
print(A_inv)              # [[-2,1],[1.5,-0.5]]

# 行列式
print(np.linalg.det(A))    # -2.0

# 特征值与特征向量
eigenvalues, eigenvectors = np.linalg.eig(A)

# 解线性方程组 Ax = b
b = np.array([1, 2])
x = np.linalg.solve(A, b)  # 求解 x

# 矩阵分解
Q, R = np.linalg.qr(A)       # QR分解
U, S, Vh = np.linalg.svd(A)  # SVD分解

广播机制(Broadcasting)

NumPy广播允许不同形状的数组之间进行运算,是NumPy最强大的特性之一。

广播规则

  1. 如果两个数组维度数不同,会在 较小维度数组 的形状前面补1,直到维度数相同
  2. 如果两个数组在某个维度上的大小 相同 ,或者其中 一个为1 ,则可以广播
  3. 如果某个维度上大小不同且都不为1,则 无法广播 ,报错
import numpy as np

# 示例1:标量广播到数组
a = np.array([1, 2, 3])
print(a + 10)              # [11, 12, 13] — 10 广播为 [10,10,10]

# 示例2:一维数组广播到二维
A = np.array([[1,2,3],[4,5,6],[7,8,9]])  # shape (3,3)
b = np.array([10,20,30])                              # shape (3,) → 变为 (1,3)
print(A + b)              # [[11,22,33],[14,25,36],[17,28,39]]

# 示例3:列向量广播
c = np.array([[10],[20],[30]])   # shape (3,1)
print(A + c)              # [[11,12,13],[24,25,26],[37,38,39]]

其他 NumPy 通用函数

数组操作

# 拼接
np.concatenate([a, b])     # 沿轴0拼接
np.vstack([a, b])          # 垂直拼接
np.hstack([a, b])          # 水平拼接
np.split(arr, 3)         # 等分

# 重复与平铺
np.tile(a, 3)            # 整体重复3次
np.repeat(a, 2)          # 每个元素重复2次

# 去重与排序
np.unique(arr)             # 唯一值
np.sort(arr, axis=0)       # 排序
np.argsort(arr)            # 排序索引
np.searchsorted(arr, 5)  # 二分查找插入位置

随机数生成

from numpy.random import default_rng
rng = default_rng(42)      # 设置随机种子

rng.random(5)              # 5个0~1随机数
rng.integers(0, 10, 5)      # 5个0~9整数
rng.normal(0, 1, 100)     # 100个正态分布数
rng.choice([1,2,3], 10)  # 随机抽样
rng.shuffle(arr)             # 原地打乱
rng.permutation(arr)         # 返回打乱副本

本章总结

掌握 NumPy 后,方可轻松驾驭 Pandas 与 Matplotlib,它们底层均依赖 NumPy。

下一章 ▶