第十四章:数据分析基础库NumPy(二)
数据分析基础库 NumPy
文章目录
- 数据分析基础库 NumPy
- 五、数组的基本运算
- 5.1 元素级运算
- 5.2 广播机制
- 5.3 矩阵运算
- 5.4 比较运算
- 六、数组的索引与切片
- 6.1 一维数组索引与切片
- 6.2 二维数组索引与切片
- 6.3 高级索引
- 七、常用函数与统计方法
- 7.1 统计函数
- 7.2 排序与去重
- 7.3 条件筛选与查找
- 八、总结
- 8.3 资源推荐
五、数组的基本运算
5.1 元素级运算
NumPy 的一个核心优势是支持向量化运算,即可以对整个数组进行数学运算,而无需显式循环。这些运算在底层是用 C 语言实现的,因此速度极快。
元素级运算:对数组中对应位置的元素进行运算,要求参与运算的数组形状相同。
支持的运算符:
运算符 | 描述 | 示例 |
---|---|---|
+ | 加法 | arr1 + arr2 |
- | 减法 | arr1 - arr2 |
* | 乘法(元素级) | arr1 * arr2 |
/ | 除法 | arr1 / arr2 |
** | 幂运算 | arr1 ** arr2 |
示例 1:数组与标量的运算
# 创建数组
arr = np.arange(5) # [0, 1, 2, 3, 4]# 数组与标量相加
add_result = arr + 2
print("数组加标量:", add_result) # 输出:[2, 3, 4, 5, 6]# 数组与标量相乘
mult_result = arr * 3
print("数组乘标量:", mult_result) # 输出:[0, 3, 6, 9, 12]
示例 2:数组与数组的运算
# 创建两个数组
arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])# 数组相加
add_result = arr1 + arr2
print("数组相加:", add_result) # 输出:[5, 7, 9]# 数组相乘(元素级)
mult_result = arr1 * arr2
print("数组相乘:", mult_result) # 输出:[4, 10, 18]
示例 3:复合运算
# 创建数组
arr = np.arange(1, 10).reshape(3, 3) # 3x3数组:[[1,2,3],[4,5,6],[7,8,9]]# 复合运算:先平方,再减10,最后除以2
result = (arr ** 2 - 10) / 2
print("复合运算结果:")
print(result)
5.2 广播机制
当对形状不同的数组进行运算时,NumPy 会自动应用广播机制,使它们能够兼容。广播机制允许较小的数组在较大的数组上进行操作,就像它们是相同形状一样。
广播规则:
-
从右到左比较维度大小
-
如果当前维度大小不匹配,且其中一个为 1,则扩展该维度
-
如果当前维度大小不匹配,且都不为 1,则无法广播,报错
示例 1:一维数组与二维数组相加
# 创建数组
arr2d = np.array([[1, 2, 3], [4, 5, 6]]) # 2x3数组
arr1d = np.array([10, 20, 30]) # 一维数组# 广播相加
result = arr2d + arr1d
print("广播相加结果:")
print(result)
输出结果:
[[11 22 33][14 25 36]]
在这个例子中,一维数组arr1d
被广播为与arr2d
相同的形状,然后进行元素级相加。
示例 2:二维数组与一维数组相乘
# 创建数组
arr2d = np.array([[1, 2, 3], [4, 5, 6]]) # 2x3数组
arr1d = np.array([10, 20]) # 一维数组# 尝试广播相乘(会报错)
# result = arr2d * arr1d # 报错:operands could not be broadcast together# 正确方式:调整arr1d的形状
arr1d_reshaped = arr1d.reshape(-1, 1) # 变为2x1数组
result = arr2d * arr1d_reshaped
print("广播相乘结果:")
print(result)
输出结果:
[[ 10 20 30][ 80 100 120]]
5.3 矩阵运算
在科学计算和机器学习中,矩阵运算是非常重要的操作。NumPy 提供了多种矩阵运算函数。
矩阵乘法:
-
np.dot()
:执行矩阵乘法,适用于一维和二维数组 -
np.matmul()
:执行矩阵乘法,更严格地遵循矩阵乘法规则 -
@
运算符:Python 3.5 + 支持的矩阵乘法运算符
示例 1:二维矩阵乘法
# 创建两个2x2矩阵
matrix1 = np.array([[1, 2], [3, 4]])
matrix2 = np.array([[5, 6], [7, 8]])# 使用np.dot进行矩阵乘法
dot_result = np.dot(matrix1, matrix2)
print("np.dot结果:")
print(dot_result)# 使用@运算符进行矩阵乘法
matmul_result = matrix1 @ matrix2
print("@运算符结果:")
print(matmul_result)
输出结果:
np.dot结果:
[[19 22][43 50]]
@运算符结果:
[[19 22][43 50]]
示例 2:多维数组矩阵乘法
# 创建3x3矩阵和3x2矩阵
matrix1 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
matrix2 = np.array([[10, 11], [12, 13], [14, 15]])# 矩阵乘法
result = matrix1 @ matrix2
print("3x3矩阵与3x2矩阵相乘结果:")
print(result)
输出结果:
[[ 70 76][151 163][232 250]]
5.4 比较运算
NumPy 支持对数组进行比较运算,返回布尔型数组,其中每个元素表示对应位置的比较结果。
比较运算符:
运算符 | 描述 | 示例 |
---|---|---|
== | 等于 | arr1 == arr2 |
!= | 不等于 | arr1 != arr2 |
> | 大于 | arr1 > arr2 |
>= | 大于等于 | arr1 >= arr2 |
< | 小于 | arr1 < arr2 |
<= | 小于等于 | arr1 <= arr2 |
示例 1:数组比较
# 创建数组
arr1 = np.array([1, 2, 3, 4, 5])
arr2 = np.array([3, 2, 5, 1, 4])# 比较运算
equal = arr1 == arr2
greater = arr1 > arr2
less_or_equal = arr1 <= arr2print("等于比较结果:", equal)
print("大于比较结果:", greater)
print("小于等于比较结果:", less_or_equal)
输出结果:
等于比较结果: [False True False False False]
大于比较结果: [False False False True True]
小于等于比较结果: [ True True True False False]
示例 2:布尔索引
# 创建数组
arr = np.array([10, 20, 30, 40, 50])# 使用布尔索引获取大于25的元素
bool_mask = arr > 25
result = arr[bool_mask]
print("大于25的元素:", result) # 输出:[30 40 50]# 直接使用条件表达式进行索引
result = arr[arr > 25]
print("直接条件索引结果:", result) # 输出:[30 40 50]
六、数组的索引与切片
6.1 一维数组索引与切片
一维数组的索引和切片操作与 Python 列表类似,但功能更强大。
基本索引:
-
正数索引:从 0 开始,
arr[0]
表示第一个元素 -
负数索引:从 - 1 开始,
arr[-1]
表示最后一个元素
切片语法:arr[start:end:step]
-
start
:起始索引(包含),默认为 0 -
end
:结束索引(不包含),默认为数组长度 -
step
:步长,默认为 1
示例 1:基本索引
# 创建一维数组
arr = np.arange(10) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]# 基本索引
print("第一个元素:", arr[0]) # 输出:0
print("最后一个元素:", arr[-1]) # 输出:9
print("第三个元素:", arr[2]) # 输出:2
示例 2:切片操作
# 切片操作
print("前5个元素:", arr[:5]) # 输出:[0, 1, 2, 3, 4]
print("从索引3到末尾:", arr[3:]) # 输出:[3, 4, 5, 6, 7, 8, 9]
print("每隔一个元素:", arr[::2]) # 输出:[0, 2, 4, 6, 8]
print("逆序数组:", arr[::-1]) # 输出:[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
6.2 二维数组索引与切片
二维数组的索引和切片需要指定行和列的索引或切片。
基本索引:
-
arr[row, col]
:获取第row
行第col
列的元素 -
arr[row][col]
:等价于上述形式,但前者更高效
切片语法:arr[row_start:row_end:row_step, col_start:col_end:col_step]
示例 1:基本索引
# 创建二维数组
arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])# 基本索引
print("第一行第二列元素:", arr2d[0, 1]) # 输出:2
print("第三行第三列元素:", arr2d[2, 2]) # 输出:9
print("第二行所有元素:", arr2d[1, :]) # 输出:[4, 5, 6]
print("第三列所有元素:", arr2d[:, 2]) # 输出:[3, 6, 9]
示例 2:切片操作
# 切片操作
print("前两行,前两列:")
print(arr2d[:2, :2]) # 输出:[[1, 2], [4, 5]]print("所有行,第三列:")
print(arr2d[:, 2:3]) # 输出:[[3], [6], [9]]print("每隔一行,每隔一列:")
print(arr2d[::2, ::2]) # 输出:[[1, 3], [7, 9]]
6.3 高级索引
除了基本索引和切片外,NumPy 还支持更高级的索引方式,如整数数组索引和布尔索引。
整数数组索引:使用整数数组作为索引,获取多个不连续的元素。
示例 1:整数数组索引
# 创建数组
arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])# 获取第一行和第三行的元素
rows = np.array([0, 2])
result = arr[rows, :]
print("整数数组索引结果:")
print(result)
输出结果:
[[1 2 3][7 8 9]]
布尔索引:使用布尔数组作为索引,获取满足条件的元素。
示例 2:布尔索引
# 创建数组
arr = np.array([10, 20, 30, 40, 50])# 创建布尔掩码
mask = arr > 25
print("布尔掩码:", mask) # 输出:[False False True True True]# 使用布尔索引获取元素
result = arr[mask]
print("布尔索引结果:", result) # 输出:[30, 40, 50]# 直接在索引中使用条件表达式
result = arr[arr > 25]
print("直接条件索引结果:", result) # 输出:[30, 40, 50]
示例 3:二维布尔索引
# 创建二维数组
arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])# 创建布尔掩码
mask = arr2d % 2 == 0 # 偶数位置为Trueprint("布尔掩码:")
print(mask)print("布尔索引结果:")
print(arr2d[mask])
输出结果:
布尔掩码:
[[False True False][ True False True][False True False]]
布尔索引结果:
[2 4 6 8]
七、常用函数与统计方法
7.1 统计函数
NumPy 提供了丰富的统计函数,用于对数组进行各种统计计算。这些函数可以在整个数组或指定轴上进行操作。
常用统计函数:
函数 | 功能 | 示例 |
---|---|---|
np.sum() | 计算数组元素的和 | np.sum(arr) |
np.mean() | 计算数组元素的平均值 | np.mean(arr) |
np.std() | 计算数组元素的标准差 | np.std(arr) |
np.var() | 计算数组元素的方差 | np.var(arr) |
np.min() | 查找数组中的最小值 | np.min(arr) |
np.max() | 查找数组中的最大值 | np.max(arr) |
np.argmin() | 查找最小值的索引 | np.argmin(arr) |
np.argmax() | 查找最大值的索引 | np.argmax(arr) |
示例 1:一维数组统计
# 创建数组
arr = np.array([10, 20, 30, 40, 50])# 统计计算
print("总和:", np.sum(arr)) # 输出:150
print("平均值:", np.mean(arr)) # 输出:30.0
print("标准差:", np.std(arr)) # 输出:约15.811
print("最大值:", np.max(arr)) # 输出:50
print("最小值索引:", np.argmin(arr)) # 输出:0
示例 2:二维数组按轴统计
# 创建二维数组
arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])# 按列统计(axis=0)
print("每列和:", np.sum(arr2d, axis=0)) # 输出:[12, 15, 18]
print("每列最大值:", np.max(arr2d, axis=0)) # 输出:[7, 8, 9]# 按行统计(axis=1)
print("每行和:", np.sum(arr2d, axis=1)) # 输出:[6, 15, 24]
print("每行平均值:", np.mean(arr2d, axis=1)) # 输出:[2.0, 5.0, 8.0]
7.2 排序与去重
排序函数:
-
np.sort()
:返回排序后的新数组,不改变原数组 -
arr.sort()
:原地排序,改变原数组
去重函数:
np.unique()
:返回数组中的唯一值,并排序
示例 1:排序操作
# 创建数组
arr = np.array([3, 1, 4, 1, 5, 9, 2, 6])# 排序并返回新数组
sorted_arr = np.sort(arr)
print("排序后的数组:", sorted_arr) # 输出:[1, 1, 2, 3, 4, 5, 6, 9]# 原地排序
arr.sort()
print("原数组已排序:", arr) # 输出:[1, 1, 2, 3, 4, 5, 6, 9]
示例 2:二维数组排序
# 创建二维数组
arr2d = np.array([[3, 1, 4], [1, 5, 9], [2, 6, 5]])# 按行排序
sorted_rows = np.sort(arr2d, axis=1)
print("按行排序:")
print(sorted_rows)# 按列排序
sorted_cols = np.sort(arr2d, axis=0)
print("按列排序:")
print(sorted_cols)
示例 3:去重操作
# 创建数组
arr = np.array([1, 2, 2, 3, 3, 3, 4, 4, 4, 4])# 去重
unique_arr = np.unique(arr)
print("去重后的数组:", unique_arr) # 输出:[1, 2, 3, 4]
7.3 条件筛选与查找
np.where()
函数:返回满足条件的元素的索引,可以用于条件筛选。
示例 1:简单条件筛选
# 创建数组
arr = np.arange(10) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]# 查找大于5的元素索引
indices = np.where(arr > 5)
print("大于5的元素索引:", indices) # 输出:(array([6, 7, 8, 9]),)# 获取满足条件的元素
values = arr[indices]
print("大于5的元素值:", values) # 输出:[6, 7, 8, 9]# 直接使用条件索引
values = arr[arr > 5]
print("直接条件索引值:", values) # 输出:[6, 7, 8, 9]
示例 2:二维数组条件筛选
# 创建二维数组
arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])# 查找大于4的元素索引
indices = np.where(arr2d > 4)
print("大于4的元素索引:", indices) # 输出:(array([1, 1, 2, 2, 2]), array([2, 1, 0, 1, 2]))# 获取满足条件的元素值
values = arr2d[indices]
print("大于4的元素值:", values) # 输出:[5, 6, 7, 8, 9]
八、总结
NumPy 库的核心内容 ——ndarray 数组的创建、属性、运算、索引与切片以及常用函数。以下重点内容:
-
ndarray 优势:高效存储、向量化运算、速度极快
-
创建方法:
-
从 Python 数据结构转换:
np.array()
-
基于数值范围生成:
np.arange()
、np.linspace()
、np.logspace()
-
预定义形状填充:
np.zeros()
、np.ones()
、np.full()
-
特殊矩阵生成:
np.eye()
、np.diag()
-
随机数组生成:
np.random.rand()
、np.random.randn()
、np.random.randint()
- 基本属性:
-
形状相关:
shape
、ndim
、size
-
数据类型相关:
dtype
、itemsize
、nbytes
- 数组运算:
-
元素级运算:支持
+
、-
、*
、/
等运算符 -
广播机制:不同形状数组间的运算
-
矩阵运算:
np.dot()
、np.matmul()
、@
运算符
- 索引与切片:
-
一维和二维数组的基本索引与切片
-
高级索引:整数数组索引、布尔索引
- 常用函数:
-
统计函数:
np.sum()
、np.mean()
、np.max()
等 -
排序与去重:
np.sort()
、np.unique()
-
条件筛选:
np.where()
8.3 资源推荐
为了进一步学习 NumPy,推荐以下资源:
- 官方文档:
-
NumPy 官方文档:https://numpy.org/doc/stable/
-
NumPy 中文文档:https://www.numpy.org.cn/
- 教程与书籍:
-
《Python 数据分析实战》(利用 Pandas、NumPy 和 Matplotlib 进行数据处理)
-
《NumPy 快速入门教程》(NumPy Quickstart Tutorial)
- 视频教程:
-
YouTube:NumPy Tutorials by Corey Schafer
-
B 站:NumPy 教程系列