Python学习(六)——配套《PyTorch深度学习实战》

1. NumPy介绍

这张图片介绍了Python中两个非常重要的科学计算库:NumPy和SciPy,以及它们的核心功能和特性。

NumPy

NumPy(Numerical Python)是一个开源的Python科学计算库,用于进行大规模数值和矩阵运算。以下是图片中提到的NumPy的关键特性:

  • NumPy数组:类似于Matlab中的矩阵,NumPy数组是NumPy的核心数据结构,用于存储同类型数据的集合。
  • 数据分析的核心基础库:NumPy提供了大量的数学函数来操作数组,使其成为数据分析和科学计算的基础。
  • 数组的生成和方法:NumPy提供了多种方法来生成数组,并提供了丰富的方法来操作这些数组。
  • 数组广播 :NumPy支持数组广播,这是一种强大的机制,允许NumPy用不同大小的数组进行算术运算。广播规则允许较小的数组"扩展"以匹配较大数组的形状,只要它们在相应的维度上兼容。例如,一个形状为2x3x1的数组可以与一个形状为5x1x3x4的数组进行运算,因为其中一个维度为1,可以广播以匹配另一个数组的相应维度。
  • 高维数组的索引(花式索引):NumPy允许使用复杂的索引技术,如花式索引,来选择数组的子集。
  • 随机数组的生成:NumPy提供了生成随机数数组的功能,这对于模拟和统计分析非常有用。

SciPy

SciPy(Scientific Python)是一个开源的Python算法库和数学工具包,用于科学和工程计算。它建立在NumPy之上,提供了更多的功能。以下是图片中提到的SciPy的关键模块:

  • 插值scipy.interpolate模块提供了各种插值方法,用于估计数据点之间的值。
  • 统计scipy.stats模块提供了统计分布、统计测试和统计数据的统计描述。
  • 优化scipy.optimize模块提供了多种优化算法,用于找到函数的最小值或最大值。
  • 积分scipy.integrate模块提供了数值积分的方法,用于计算定积分或不定积分。
  • 线代scipy.linalg模块提供了线性代数的基本操作,包括矩阵分解、特征值问题等。

这两个库是Python科学计算生态系统的基石,广泛应用于数据科学、机器学习、工程和科学领域。


2. 列表和数组的区别

数组(Arrays)和列表(Lists)是编程中用于存储多个值的两种不同的数据结构,它们在不同编程语言中有着不同的实现和特性。在Python中,列表是一种内置的数据结构,而数组则通常通过第三方库(如NumPy)实现。以下是数组和列表在Python中的主要区别:

1. 元素类型

  • 列表:可以包含不同类型的元素,例如整数、字符串、浮点数、甚至是其他列表或对象。列表是异构的。
  • NumPy数组:通常要求所有元素都是相同的数据类型,这使得数组在处理数值计算时更加高效。数组是同构的。

2. 性能

  • 列表:由于其灵活性,列表在执行数值计算时可能不如数组高效,尤其是在处理大量数据时。
  • NumPy数组:为了提高性能,NumPy数组在内存中是连续存储的,这使得它们在进行向量化操作时非常快速。

3. 内存使用

  • 列表:由于存储了元素的类型信息,列表可能使用更多的内存。
  • NumPy数组:因为所有元素类型相同,数组可以更紧凑地存储数据,通常使用更少的内存。

4. 功能和方法

  • 列表 :Python的列表提供了丰富的方法,如append(), extend(), insert(), remove(), pop()等,用于添加、删除和修改元素。
  • NumPy数组 :NumPy数组提供了大量的数学和统计方法,这些方法在列表中不可用,如mean(), std(), sum(), cumprod()等。

5. 索引和切片

  • 列表:支持基于0的索引和负索引,以及切片操作。
  • NumPy数组:同样支持基于0的索引、负索引和切片,但还支持更高级的索引技术,如花式索引和布尔索引。

6. 广播

  • 列表:不支持广播机制。
  • NumPy数组:支持广播,这是一种强大的机制,允许NumPy用不同大小的数组进行算术运算。

7. 可变性

  • 列表:是可变的,意味着你可以在不改变列表身份的情况下更改其内容。
  • NumPy数组:也是可变的,但对数组的某些操作(如改变形状或大小)会创建一个新的数组。

8. 使用场景

  • 列表:适用于存储不同类型的数据,或者当你需要存储的数据结构不规则时。
  • NumPy数组:适用于数值计算,特别是当你需要处理大量数值数据并进行向量化操作时。

在Python中,如果你需要进行高效的数值计算,使用NumPy数组通常是更好的选择。如果你需要一个灵活的数据结构来存储不同类型的数据,那么列表可能更合适。

对两者进行形象化的解释

让我们通过一些比喻来形象化地解释Python中数组和列表的区别:

列表(Lists):购物清单

想象一下,你有一个购物清单,上面可以写任何你想要的东西,无论是苹果、牛奶还是洗洁精。你可以在清单上添加新项目,划掉已经购买的物品,或者在任何位置插入新项目。这个清单没有严格的规则,你可以随意修改它。

  • 灵活性:就像购物清单可以包含任何商品,Python列表可以包含任何类型的元素。
  • 修改:你可以在购物清单上自由添加或删除项目,同样,Python列表也允许你添加、删除或修改元素。

数组(Arrays):图书馆的书架

现在,想象一下图书馆里的书架。每个书架(数组)都是为特定类型的书设计的,比如小说、科学或历史。你不能在小说书架上放一本科学书。书架上的书籍按照一定的顺序排列,你可以通过编号快速找到它们。

  • 统一性:图书馆的每个书架都只存放一种类型的书,同样,NumPy数组中的所有元素必须是相同的数据类型。
  • 效率:图书馆的书籍按照编号排列,使得查找变得非常快速。NumPy数组在内存中连续存储,这使得它们在进行数值计算时非常高效。

性能:赛车与普通汽车

  • 列表:就像一辆普通汽车,它可以在各种道路上行驶,但可能不是最快的。在处理大量数据或需要高性能计算时,列表可能不是最高效的选择。
  • NumPy数组:就像一辆赛车,它在直道上(数值计算)可以跑得非常快,但在曲折的山路上(复杂的数据结构)可能不太灵活。

内存使用:小房子与大房子

  • 列表:就像一个小房子,每个房间(元素)都可以存放不同的东西,但可能需要更多的空间来存放各种物品。
  • NumPy数组:就像一个大房子,所有房间(元素)都是相同的,这使得空间利用更加高效,但可能不允许存放不同类型的物品。

通过这些比喻,我们可以更直观地理解Python中列表和数组的区别,以及它们在不同场景下的适用性。列表提供了灵活性和多样性,而数组提供了效率和统一性。


3. Python中的数据类型

在Python中,数组通常是指NumPy库中的数组,它们支持多种数据类型。NumPy数组的数据类型(dtype)决定了数组中每个元素的存储方式和所占空间。以下是一些常见的NumPy数据类型:

  1. 整数类型

    • int8:8位有符号整数
    • int16:16位有符号整数
    • int32:32位有符号整数
    • int64:64位有符号整数
    • uint8:8位无符号整数
    • uint16:16位无符号整数
    • uint32:32位无符号整数
    • uint64:64位无符号整数
  2. 浮点类型

    • float16:16位半精度浮点数
    • float32:32位单精度浮点数
    • float64:64位双精度浮点数
    • float128:128位扩展精度浮点数(在某些平台上可用)
  3. 复数类型

    • complex64:64位复数(32位实部和32位虚部)
    • complex128:128位复数(64位实部和64位虚部)
    • complex256:256位复数(在某些平台上可用)
  4. 布尔类型

    • bool_:布尔类型,用于存储True或False值
  5. 对象类型

    • object_:可以存储Python对象的数组
  6. 字符串类型

    • str_:字符串类型,用于存储文本数据
    • bytes_:字节类型,用于存储原始字节数据
    • unicode_:Unicode字符串类型,用于存储Unicode文本数据
  7. 日期和时间类型

    • datetime64:日期和时间类型,可以指定不同的时间分辨率,如datetime64[s]表示秒级分辨率
  8. 时间差类型

    • timedelta64:时间差类型,用于表示两个日期或时间之间的差异
  9. 自定义类型

    • 用户可以定义自己的数据类型,通过组合现有的数据类型来创建结构化数组。

NumPy数组的dtype是固定的,这意味着一旦数组被创建,其dtype就不能改变。如果你需要改变数组的数据类型,你必须创建一个新的数组。例如:

python 复制代码
import numpy as np

# 创建一个整数数组
int_array = np.array([1, 2, 3], dtype=np.int32)

# 创建一个浮点数数组
float_array = np.array([1.0, 2.0, 3.0], dtype=np.float64)

# 创建一个布尔数组
bool_array = np.array([True, False, True], dtype=np.bool_)

# 创建一个字符串数组
str_array = np.array(['hello', 'world'], dtype=np.str_)

在创建数组时,你可以指定dtype参数来定义数组的数据类型。如果不指定,NumPy会根据提供的元素自动推断dtype。


4. 数组中axis是什么

在NumPy和类似库中,axis是一个非常重要的概念,它用于指定在多维数组(如矩阵)上进行操作的维度。axis参数在许多NumPy函数中都有出现,比如mean(), std(), sum(), argmax()等,它允许你指定沿着哪个轴进行计算。

理解axis

在二维数组(矩阵)中,axis可以取以下几个值:

  • axis=0:沿着列操作,即对每一列的元素进行操作。这通常意味着函数将应用于数组的每一行。
  • axis=1:沿着行操作,即对每一行的元素进行操作。这通常意味着函数将应用于数组的每一列。

在更高维度的数组中,axis可以是任何从0到n-1的整数(其中n是数组的维度数),表示沿着第axis个维度进行操作。

示例

假设你有一个二维数组,表示为一个矩阵:

python 复制代码
import numpy as np

# 创建一个3x3的数组
array_2d = np.array([[1, 2, 3],
                     [4, 5, 6],
                     [7, 8, 9]])

如果你想计算每一列的平均值,你可以这样做:

python 复制代码
mean_by_column = np.mean(array_2d, axis=0)

这将返回一个包含每列平均值的一维数组:[4., 5., 6.]

相反,如果你想计算每一行的平均值,你可以这样做:

python 复制代码
mean_by_row = np.mean(array_2d, axis=1)

这将返回一个包含每行平均值的一维数组:[2., 5., 8.]

多维数组

对于多维数组,axis的概念扩展到更多的维度。例如,一个三维数组可以看作是一个"堆叠"的矩阵,你可以沿着第一个维度(axis=0)、第二个维度(axis=1)或第三个维度(axis=2)进行操作。

注意事项

  • 如果不指定axis,某些函数可能会返回一个降维的结果,或者在所有元素上进行操作。
  • 在使用axis时,确保它不超过数组的维度数减一(例如,对于三维数组,axis的有效值是0、1或2)。

通过理解axis,你可以更精确地控制NumPy函数在多维数组上的操作维度,这对于数据分析和科学计算至关重要。


5. 如何用numpy实现矩阵

直接写就可以

在Python中,使用NumPy库可以方便地实现矩阵的各种操作。以下是一些基本的步骤和示例,展示如何使用NumPy来创建和操作矩阵:

1. 安装NumPy

如果你还没有安装NumPy,可以通过pip安装:

bash 复制代码
pip install numpy

2. 导入NumPy

在Python脚本或交互式环境中导入NumPy:

python 复制代码
import numpy as np

3. 创建矩阵

有多种方式可以创建NumPy矩阵:

从列表创建矩阵

python 复制代码
# 使用嵌套列表创建矩阵
matrix = np.array([[1, 2, 3],
                   [4, 5, 6],
                   [7, 8, 9]])
print(matrix)

使用np.zeros创建零矩阵

python 复制代码
# 创建一个3x3的零矩阵
zero_matrix = np.zeros((3, 3))
print(zero_matrix)

使用np.ones创建单位矩阵

python 复制代码
# 创建一个3x3的单位矩阵
ones_matrix = np.ones((3, 3))
print(ones_matrix)

使用np.eye创建对角矩阵

python 复制代码
# 创建一个3x3的对角矩阵
identity_matrix = np.eye(3)
print(identity_matrix)

使用np.random创建随机矩阵

python 复制代码
# 创建一个3x3的随机矩阵
random_matrix = np.random.rand(3, 3)
print(random_matrix)

4. 矩阵的基本操作

矩阵加法

python 复制代码
# 矩阵加法
matrix1 = np.array([[1, 2], [3, 4]])
matrix2 = np.array([[5, 6], [7, 8]])
sum_matrix = matrix1 + matrix2
print(sum_matrix)

矩阵乘法

python 复制代码
# 矩阵乘法
product_matrix = np.dot(matrix1, matrix2)
print(product_matrix)

矩阵转置

python 复制代码
# 矩阵转置
transpose_matrix = matrix1.T
print(transpose_matrix)

矩阵的逆

python 复制代码
# 矩阵的逆(需要是方阵)
if matrix1.shape[0] == matrix1.shape[1]:
    inverse_matrix = np.linalg.inv(matrix1)
    print(inverse_matrix)

矩阵的行列式

python 复制代码
# 矩阵的行列式(需要是方阵)
if matrix1.shape[0] == matrix1.shape[1]:
    det = np.linalg.det(matrix1)
    print(det)

5. 高级操作

NumPy提供了许多用于矩阵运算的高级函数,如特征值、奇异值分解等,这些都可以在numpy.linalg模块中找到。

通过这些基本步骤,你可以开始使用NumPy进行矩阵运算和更复杂的数值计算。NumPy的文档提供了更详细的信息和高级功能。

矩阵乘法的实现

执行矩阵乘法

在NumPy中,可以使用dot()函数或者@运算符来执行矩阵乘法:

使用dot()函数

使用dot函数进行矩阵乘法

product = np.dot(matrix_a, matrix_b)

print("Matrix product using dot():\n", product)

使用@运算符

使用@运算符进行矩阵乘法

product = matrix_a @ matrix_b

print("Matrix product using @ operator:\n", product)


6. 广播机制

NumPy数组的广播(Broadcasting)机制是一种强大的特性,它允许NumPy在执行数组运算时,自动扩展较小的数组以匹配较大数组的形状。这种机制在不实际复制数据的情况下,提供了一种便捷的方式来执行数组间的算术运算。广播机制遵循以下规则:

  1. 维度匹配:从两个数组的尾部(最右边)开始比较维度,如果两个数组在某个维度上的长度相同,或者其中一个数组在该维度上的长度为1,则认为这两个维度是兼容的。

  2. 广播扩展:如果一个数组在某个维度上的长度为1,NumPy会将其沿着该维度扩展以匹配另一个数组的形状。这意味着长度为1的维度可以被视为任何长度。

  3. 逐元素运算:一旦两个数组的形状兼容,NumPy就会逐元素地执行运算。在扩展后的数组中,每个元素都会与另一个数组中相应位置的元素进行运算。

广播示例

假设有两个数组 ab

python 复制代码
import numpy as np

a = np.array([1, 2, 3])  # 形状为 (3,)
b = np.array([[1], [2], [3]])  # 形状为 (3, 1)

尽管 ab 的形状不同,但它们在进行逐元素加法时可以广播:

python 复制代码
c = a + b  # 结果的形状为 (3, 3)

在执行加法时,a 会在列方向上广播,b 会在行方向上广播,以匹配对方的形状。结果是:

[[2 2 3]
 [3 4 5]
 [4 5 6]]

广播的维度规则

  • 如果两个数组的维度不同,那么较小维度的数组会在前面补1,直到两个数组的维度相同。
  • 如果两个数组在某个维度上的长度相同,或者其中一个数组在该维度上的长度为1,那么这两个数组在该维度上是兼容的。
  • 如果两个数组在某个维度上的长度都不为1,且不相等,那么它们在该维度上不兼容,不能进行广播。

广播的用途

广播机制在NumPy中非常有用,因为它允许你:

  • 进行不同大小数组间的运算,而不需要显式地重塑数组。
  • 简化代码,减少内存使用,因为不需要复制数据来扩展数组。
  • 轻松实现向量化操作,如将一个值加到数组的每个元素上,或者比较数组与标量的每个元素。

广播是NumPy中实现高效数值计算的关键特性之一。

相关推荐
CSJK-1 小时前
模式识别与机器学习 | 十一章 概率图模型基础
人工智能·深度学习·机器学习
江左子固2 小时前
《计算机体系结构与SoC设计》(二)
架构学习·书籍阅读
余胜辉3 小时前
随机梯度下降(SGD)算法的深度剖析与应用探索
深度学习·机器学习·优化算法·sgd·随机梯度下降
Power20246663 小时前
NLP论文速读|基于主动检索的渐进多模态推理
人工智能·深度学习·机器学习·自然语言处理·nlp
研一计算机小白一枚4 小时前
Deep blind super-resolution for hyperspectral images_译文
人工智能·深度学习·计算机视觉
狂奔solar4 小时前
图神经网络在yelp数据集上分析用户如何影响彼此的评价
人工智能·深度学习·神经网络
深鱼~5 小时前
【多线程初阶篇 ²】创建线程的方式
java·开发语言·jvm·深度学习·神经网络·opencv
铮铭6 小时前
DINOv2+Qwen2.5-VL-2B+LoRA实现image caption的微调
python·深度学习·机器学习·具身智能·vla
梁小憨憨7 小时前
深度学习中的正则化方法
人工智能·笔记·深度学习
gs801407 小时前
使用 TFJob 进行分布式深度学习任务的多 GPU 协调指南
人工智能·分布式·深度学习·tensorflow·kubeflow·tfjob