day14numpy
NumPy
基础
1.1概念
NumPy(Numeric Python)是Python的第三方扩展包,主要用于计算和处理一维或多维数组。它在数组算术计算方面提供了大量数学函数,底层用C语言编写,能够高速执行数值计算。NumPy的数据结构非常适合数组和矩阵的运算。
1.2 优点
1.是Python科学计算的基础库。
2.可对数组进行高效的数学运算。
3.ndarray对象用于构建多维数组。
4.能够执行傅立叶变换与重塑多维数组形状。
5.提供了线性代数及随机数生成的内置函数。
1.3 与Python列表的区别
1.NumPy数组是同质的(homogeneous),即所有元素必须是相同的数据类型,在创建时指定。
2.Python列表是异质的(heterogeneous),可以包含不同类型的数据。
3.NumPy数组提供了丰富的数学函数和操作,如矩阵运算、线性代数等。
4.Python列表提供基本的列表操作,如添加、删除、切片、排序等。
1.4 安装
NumPy可以通过Python的包管理工具pip进行安装。例如:
pip install numpy -i https://pypi.tuna.tsinghua.edu.cn/simple/
ndarray
通过array函数或其他NumPy函数(如zeros、ones、arange等)创建。
提供了丰富的数学函数和操作,如矩阵运算、线性代数等。
在内存中是连续存储的,数组的访问和操作非常高效。
数据类型
NumPy提供了比Python更丰富的数据类型,包括:
布尔型(bool_)
多种整数类型(如int8、int16、int32、int64、uint8等)
多种浮点数类型(如float16、float32、float64)
复数类型(如complex64、complex128)
字符串类型(str_、U)
时间间隔(m)和日期时间(M)
Python对象类型(O)
字节串(S、a)和Unicode(U)
原始数据(V)
数据类型对象
在创建数组时指定 dtype 参数来定义数组中元素的数据类型。
使用数组的 dtype 属性来获取数组中元素的数据类型。
使用 astype() 方法来转换数组中元素的数据类型。
数组属性
shape:返回数组维度的元组,或用于调整数组维度大小。
ndim:返回数组的维数。
itemsize:返回数组中每个元素的大小(以字节为单位)。
flags:返回ndarray数组的内存信息。
创建数组的其他方法
empty():创建一个指定形状和数据类型但未初始化的数组。
zeros():创建一个指定形状和数据类型并初始化为零的数组。
ones():创建一个指定形状和数据类型并初始化为一的数组。
arange():根据指定的起始值、终止值和步长生成一个一维数组。
linspace():在指定的数值区间内返回均匀间隔的一维等差数组。
Slice()
在 NumPy 中,slice 对象提供了一种灵活的方式来获取数组的子集或片段。与 Python 中的标准切片操作类似,NumPy 允许你创建一个 slice 对象,并利用它来访问数组的一部分内容。
1. Slice 对象的基本概念
slice 是一个内置对象,通常用于数组的切片操作。你可以通过指定开始位置(start)、结束位置(stop)和步长(step)来创建一个 slice 对象。然后,可以使用这个对象作为索引来访问数组的元素。
start:切片开始的位置(包含该位置)。
stop:切片结束的位置(不包含该位置)。
step:切片的步长,即选取元素的间隔。
使用 Slice 对象进行数组切片
在 NumPy 中,ndarray 对象支持使用 slice 对象进行索引。这意味着你可以创建一个 slice 对象,并将其作为索引传递给数组,以获取所需的部分数组。
Slice 对象的参数解释
start:指定切片的起始位置。如果省略,则默认为数组的起始位置(索引0)。
stop:指定切片的结束位置。注意,切片不包含该位置的元素。如果省略,则默认为数组的结束位置。
step:指定切片的步长。如果省略,则默认为1,表示逐个元素地选取。
应用 Slice 对象
多维数组切片:在多维数组中,你可以为每个维度指定一个 slice 对象来进行切片操作。这样,你可以从多维数组中提取出任意形状的子数组。
动态切片:在某些情况下,你可能需要动态地指定切片的参数。这可以通过在运行时计算 start、stop 和 step 的值来实现。
索引
高级索引
NumPy 中的高级索引是一种强大的功能,它允许使用整数数组、布尔数组或其他序列来访问和操作数组的元素。这种索引方式比基本索引更加灵活,可以实现对数组的复杂操作和修改。
整数数组索引
整数数组索引是指使用一个数组(索引数组)来访问另一个数组(目标数组)的元素。索引数组中的每个元素都指定了目标数组中某个维度上的索引值。通过这种方式,可以一次性访问目标数组中的多个元素,可以选取特定位置的元素。以及可以实现复杂的元素选择。
使用整数数组进行索引,具体来说,当使用整数数组索引时,索引数组中的每个元素都会作为目标数组对应维度上的索引,从而选取出目标数组中对应的元素。如果索引数组是多维的,那么会按照索引数组的形状来选取目标数组中的元素,形成一个新的数组。
布尔索引
1.布尔索引是一种通过布尔运算(如比较运算符)来获取符合指定条件的元素的数组的方法。允许根据条件表达式的结果(True 或 False)来选择数组中的元素。
2.在使用布尔索引时,首先需要构造一个布尔数组,其形状与目标数组相同。布尔数组中的每个元素都对应目标数组中的一个元素,并表示该元素是否满足指定的条件。然后,通过布尔数组来索引目标数组,从而获取所有满足条件的元素。
3.布尔索引非常直观且易于使用,它允许对数组进行复杂的条件筛选和操作。例如,可以使用布尔索引来筛选出数组中大于某个值的所有元素,或者根据多个条件组合来筛选元素。
案例1:一维数组的布尔索引
假设我们有一个一维数组 `arr`,我们想要获取所有大于5的元素。可以使用布尔索引来实现这一点:
python
import numpy as np
# 创建一个一维数组
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
# 使用布尔索引筛选大于5的元素
bool_idx = arr > 5
result = arr[bool_idx]
print(result) # 输出: [6 7 8 9 10]
案例2:二维数组与一维数组相加
import numpy as np
# 创建一个二维数组
arr2d = np.array([[1, 2, 3], [4, 5, 6]])
# 创建一个一维数组
arr1d = np.array([10, 20, 30])
# 相加
result = arr2d + arr1d
print(result)
# 输出:
# [[11 22 33]
# [14 25 36]]
arr1d 被广播到与 arr2d 相同的形状,然后进行逐元素相加。
案例3:二维数组与二维数组相加
import numpy as np
# 创建一个二维数组
arr2d = np.array([[1, 2, 3], [4, 5, 6]])
# 创建一个形状为 (1, 3) 的二维数组
arr2d_broadcast = np.array([[10, 20, 30]])
# 相加
result = arr2d + arr2d_broadcast
print(result)
# 输出:
# [[11 22 33]
# [14 25 36]]
arr2d_broadcast 被广播到与 arr2d 相同的形状,然后进行逐元素相加。
广播
NumPy支持广播机制,允许在不同大小的数组上进行算术运算。
广播(Broadcast)是NumPy中一种强大的机制,它允许numpy对不同形状(shape)的数组进行数值计算。这种计算通常在相应的元素上进行,但要求这些元素的维数相同且各维度的长度也相同。当维数或维度长度不匹配时,广播机制就会发挥作用,通过对形状较小的数组在横向或纵向上进行一定次数的重复(也称为“扩展”或“映射”),使其形状与较大的数组相匹配,从而进行元素级的算术运算。
广播规则详解
维度匹配:
当两个数组的维度数不同时,NumPy会自动在维度数较少的数组前面补上长度为1的维度,直到两个数组的维度数相同。
例如,一个形状为(3,)的一维数组与一个形状为(1, 3)的二维数组进行运算时,一维数组会被视为(1, 3)的形状,以匹配二维数组的形状。
长度匹配:
在进行广播时,如果两个数组在某个维度上的长度不同,但其中一个数组在该维度上的长度为1,则NumPy会沿着这个维度对长度为1的数组进行扩展,直到其长度与另一个数组在该维度上的长度相同。
例如,一个形状为(1, 3)的数组与一个形状为(2, 3)的数组进行运算时,(1, 3)形状的数组会在第一个维度上被扩展为(2, 3),以匹配(2, 3)形状数组的形状。
不匹配情况:
如果两个数组在某个维度上的长度既不相同也不为1,则无法进行广播,NumPy会抛出一个ValueError异常。
例如,一个形状为(2, 3)的数组无法与一个形状为(2, 4)的数组进行广播,因为它们在第二个维度上的长度不匹配,且没有一个数组在该维度上的长度为1。
案例4:广播失败
import numpy as np
# 创建一个二维数组
arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
# 创建一个形状为 (2, 3) 的二维数组
arr2d_broadcast = np.array([[10, 20, 30], [40, 50, 60]])
# 尝试相加
try:
result = arr2d + arr2d_broadcast
except ValueError as e:
print(e) # 输出: operands could not be broadcast together with shapes (3,3) (2,3)