note4-python syntax

85 阅读5分钟

numpy

🔹 什么是 NumPy?

NumPy(Numerical Python) 是 Python 里最重要的 数值计算库,用于处理 多维数组(ndarray) ,并提供 矩阵运算、数学函数、随机数生成 等功能。

NumPy 的计算速度比 Python 内置的列表(list)快,因为它使用了 C 语言实现的底层优化


🔹 为什么用 NumPy?

  • 比 Python 列表快 🚀(基于 C 语言实现,避免了 Python 的循环开销)。
  • 节省内存 💾(NumPy 的数组是固定类型,比 Python 的 list 省空间)。
  • 支持向量化运算 🔢(不用写 for 循环,直接对整个数组进行计算)。
  • 功能强大 🎯(支持矩阵运算、线性代数、统计分析等)。

🔹 NumPy 基本用法

✅ 1. 安装 NumPy

pip install numpy

✅ 2. 导入 NumPy

import numpy as np  # 约定俗成,大家都用 np 作为 NumPy 的别名

✅ 3. 创建数组(ndarray)

arr = np.array([1, 2, 3, 4, 5])  # 1D 数组
print(arr)  # [1 2 3 4 5]
print(arr.shape)  # (5,) 表示长度为 5 的一维数组

创建多维数组:

arr2d = np.array([[1, 2, 3], [4, 5, 6]])  # 2D 数组
print(arr2d)
# [[1 2 3]
#  [4 5 6]]

print(arr2d.shape)  # (2, 3) 表示 2 行 3 列

✅ 4. 切片规则(slice)

Python 中的切片规则(slice)用于从序列(如列表、元组、字符串等)中提取子序列。它的基本语法是:

sequence[start:end:step]
  • start:起始索引,表示切片从该位置开始(包括该位置)。如果省略,默认为 0(从序列开始)。

  • end:结束索引,表示切片到该位置结束(不包括该位置)。如果省略,默认为序列的最后一个位置。

  • step:步长,表示切片时的间隔。默认步长为 1。如果省略,默认为 1。

切片的几个例子:
  1. 基本切片

    s = [0, 1, 2, 3, 4, 5]
    print(s[1:4])  # 输出 [1, 2, 3],包含索引 1 到 3 的元素,不包括索引 4
    
  2. 省略 startend

    print(s[:3])  # 输出 [0, 1, 2],从开始到索引 2(不包括 3)
    print(s[2:])  # 输出 [2, 3, 4, 5],从索引 2 到末尾
    
  3. 使用 step

    print(s[::2])  # 输出 [0, 2, 4],步长为 2,从开始到结束
    
  4. 负数索引

    print(s[-4:-1])  # 输出 [2, 3, 4],从倒数第 4 个元素到倒数第 2 个元素
    
  5. 反向切片

    print(s[::-1])  # 输出 [5, 4, 3, 2, 1, 0],反转整个序列
    
  6. numpy 切片

    arr = np.array([10, 20, 30, 40, 50])
    print(arr[1:4])  # [20 30 40]  切片 [起始:结束],不包含结束索引
    
    arr2d = np.array([[1, 2, 3], [4, 5, 6]])
    print(arr2d[:, 1])  # 取所有行的第 2 列 [2 5]
    print(arr2d[1, :])  # 取第 2 行 [4 5 6]
    

切片会返回一个新序列,而不会修改原序列。

🔹 常见功能

✅ 1. 生成特殊数组

np.zeros((3, 3))  # 生成 3×3 的全零矩阵
np.ones((2, 4))   # 生成 2×4 的全 1 矩阵
np.eye(3)         # 生成 3×3 的单位矩阵
np.random.rand(3, 3)  # 生成 3×3 的随机数组(0~1 之间)

✅ 2. 数组运算(支持向量化)

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

print(a + b)  # [5 7 9]
print(a * b)  # [ 4 10 18]
print(a ** 2) # [1 4 9]
print(np.exp(a)) # [ 2.71828183  7.3890561  20.08553692]  计算 e^x

向量化运算 让你不用写 for 循环,直接对整个数组进行计算,效率比 Python list 快得多!


✅ 3. 统计函数

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

print(np.mean(arr))  # 计算均值 3.5
print(np.sum(arr))   # 计算总和 21
print(np.max(arr))   # 最大值 6
print(np.min(arr))   # 最小值 1
print(np.std(arr))   # 计算标准差
print(np.var(arr))   # 计算方差

✅ 4. 矩阵运算(线性代数)

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

print(np.dot(A, B))  # 矩阵乘法
print(np.linalg.inv(A))  # 计算 A 的逆矩阵
print(np.linalg.det(A))  # 计算行列式

✅ 5. 计算L2距离(欧几里得距离)

l2_distances = np.linalg.norm(query_vec - question_vecs, axis=1)
  • query_vec:一个向量,表示查询的数据点(比如某个问题的特征向量)。

  • question_vecs:一个矩阵,表示多个问题的特征向量,每一行是一个向量。

  • query_vec - question_vecs:对每一行做向量减法,得到 query_vec 和每个 question_vecs 之间的差向量。

  • np.linalg.norm(..., axis=1):对每个差向量计算 L2 范数(即欧几里得距离)。

  • axis=1表示对行计算 ; axis=0 表示对列计算

L2 距离(欧几里得距离)的计算公式:

qxi=j(qjxi,j)2∥q-x_i∥=\sqrt{ \sum_j(q_j-x_{i,j})^2 }

其中:

  • qqquery_vec,维度为 (d,)
  • xix_iquestion_vecs 中的第 ii 个向量,维度为 (d,)
  • 结果 l2_distances[i] 表示 query_vecquestion_vecs[i] 之间的欧几里得距离。

假设:

import numpy as np

query_vec = np.array([1, 2])  # 查询向量
question_vecs = np.array([
    [2, 3],
    [3, 5],
    [0, 1]
])  # 一组向量

l2_distances = np.linalg.norm(query_vec - question_vecs, axis=1)
print(l2_distances)

计算步骤:

  • query_vec - question_vecs

    [[1-2, 2-3],  # [-1, -1]
     [1-3, 2-5],  # [-2, -3]
     [1-0, 2-1]]  # [1, 1]
    
  • 计算每个向量的 L2 范数:

    sqrt((-1)^2 + (-1)^2) = sqrt(2) ≈ 1.41
    sqrt((-2)^2 + (-3)^2) = sqrt(13) ≈ 3.61
    sqrt((1)^2 + (1)^2) = sqrt(2) ≈ 1.41
    
  • 输出:

    [1.41421356 3.60555128 1.41421356]
    

🔹 NumPy VS Python 列表

功能NumPyPython 列表
存储方式固定类型(高效)可变类型(占空间大)
运算速度快(C 语言优化) 🚀慢(Python 解释执行) 🐢
向量化计算支持(不需要 for 循环)不支持(需要 for 循环)
矩阵运算支持(dot、inv、det 等)不支持(要用额外库)

🔹 总结

  • NumPy 是 Python 科学计算的核心库,用于处理 多维数组、矩阵运算和数学计算
  • 比 Python 列表更快、更省空间,并且支持 向量化计算
  • 广泛用于数据分析、机器学习、数值计算等领域,如 Pandas、TensorFlow、SciPy 都基于它。