1. 为什么要学习NumPy?
NumPy(Numerical Python)是一个用于处理数组的Python库,学习机器学习的过程中先学会使用NumPy是非常重要的,为什么要学习NumPy呢?原因如下:
-
数组操作和运算:NumPy提供了高效的数组操作和数学运算功能,这对于处理和转换数据是至关重要的。在机器学习中,你经常需要对数据进行处理、转换和重塑,使用NumPy可以方便地进行这些操作。
-
高性能计算:NumPy是基于C语言实现的,它的计算效率非常高。在机器学习中,处理大规模的数据和进行复杂的数学计算是很常见的。NumPy提供了高性能的数组操作和数学运算,能够有效地处理这些任务。
-
数据表示和处理:在机器学习中,数据通常以多维数组的形式表示。NumPy提供了灵活和高效的多维数组操作,使你能够方便地表示和处理各种类型的数据,包括图像、文本等。
-
库的依赖性:许多常用的机器学习库和框架,如Scikit-learn、TensorFlow和PyTorch,都依赖于NumPy。学会使用NumPy可以帮助你更好地理解和使用这些库和框架,以便更好地进行机器学习任务。
综上所述,学习机器学习之前先学会使用NumPy是为了更好地处理和处理数据、进行高性能计算,并为后续学习和使用其他机器学习库打下坚实的基础。
2.安装使用NumPy
首先,我们需要确保已经安装了NumPy库。可以通过在终端或命令提示符中运行以下命令来安装NumPy:
pip install numpy
安装完成后,我们就可以开始使用NumPy。
#导入NumPy库
import numpy as np
3.NumPy创建数组
NumPy最强大的功能之一是创建多维数组。我们可以使用NumPy的array()
函数来创建数组。
例如,我们可以创建一个一维数组:
arr = np.array([1, 2, 3, 4, 5])
print(arr)
输出:
[1 2 3 4 5]
我们也可以创建一个二维数组:
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr)
输出:
[[1 2 3]
[4 5 6]]
3.1 数组属性
NumPy数组有许多重要的属性,可以帮助我们了解数组的特征。
arr = np.array([1, 2, 3, 4, 5])
print("数组形状:", arr.shape)
print("数组维度:", arr.ndim)
print("数组元素总数:", arr.size)
print("数组数据类型:", arr.dtype)
输出:
数组形状: (5,)
数组维度: 1
数组元素总数: 5
数组数据类型: int32
3.2 数组操作
NumPy提供了许多数组操作的功能,例如数组索引、切片和形状变换等。
arr = np.array([1, 2, 3, 4, 5])
print("第一个元素:", arr[0])
print("前两个元素:", arr[:2])
print("倒数三个元素:", arr[-3:])
输出:
第一个元素: 1
前两个元素: [1 2]
倒数三个元素: [3 4 5]
3.3 数组运算
NumPy支持对数组进行基本的数学运算,例如加法、减法、乘法和除法。
arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])
print("加法:", arr1 + arr2)
print("减法:", arr1 - arr2)
print("乘法:", arr1 * arr2)
print("除法:", arr1 / arr2)
输出:
加法: [5 7 9]
减法: [-3 -3 -3]
乘法: [ 4 10 18]
除法: [0.25 0.4 0.5 ]
3.4 常用函数
NumPy还提供了许多常用的函数,例如求和、平均值、最大值和最小值。
arr = np.array([1, 2, 3, 4, 5])
print("求和:", np.sum(arr))
print("平均值:", np.mean(arr))
print("最大值:", np.max(arr))
print("最小值:", np.min(arr))
输出为:
求和: 15
平均值: 3.0
最大值: 5
最小值: 1
4. NumPy高级用法
4.1 广播(Broadcasting)
NumPy数组广播是一种自动执行元素级操作的机制。它可以使具有不同形状的数组在算术运算中表现得像具有相同形状的数组一样。这种机制大大简化了对不同形状数组之间的操作。
下面是一个示例代码,演示了如何使用广播来执行数组的加法运算:
import numpy as np
arr1 = np.array([[1, 2, 3],
[4, 5, 6]])
arr2 = np.array([10, 20, 30])
result = arr1 + arr2
print(result)
在上面的代码中,arr1
是一个形状为 (2, 3) 的二维数组,arr2
是一个形状为 (3,) 的一维数组。根据广播规则,arr2
实际上被扩展为了形状为 (2, 3) 的二维数组,其中每一行都是 arr2
。然后,数组 arr1
和扩展后的 arr2
进行元素级加法运算,得到了最终的结果。
输出结果为:
[[11 22 33]
[14 25 36]]
通过广播机制,我们可以直接对不同大小的数组执行加法操作,而不需要手动进行数组形状的调整。这样可以大大简化代码,并提高效率。同时,广播机制也可以应用于其他的 NumPy 函数和运算中。
4.2 高级索引
NumPy提供了多种高级索引技巧,用于访问数组的特定位置。以下是三种常用的高级索引方法:
- 整数数组索引:使用一个整数数组作为索引,可以选择数组中的特定元素。
import numpy as np
a = np.array([1, 2, 3, 4, 5])
# 使用整数数组索引获取指定位置的元素
indices = np.array([1, 3])
result = a[indices]
print(result)
输出:
[2, 4]
- 布尔数组索引:使用一个布尔数组作为索引,可以根据布尔数组的元素值来选择数组中的元素。
import numpy as np
a = np.array([1, 2, 3, 4, 5])
# 使用布尔数组索引选择大于3的元素
mask = a > 3
result = a[mask]
print(result)
输出:
[4, 5]
还可以按布尔数组进行匹配
arr = np.array([1, 2, 3, 4, 5])
mask = np.array([True, False, True, False, True]) # 选择为True的元素
print(arr[mask]) # 输出 [1 3 5]
- 花式索引(Fancy indexing):使用整数数组或整数列表作为索引,可以根据指定的索引位置选择数组中的元素。
import numpy as np
a = np.array([1, 2, 3, 4, 5])
# 使用花式索引获取指定位置的元素
indices = np.array([0, 2, 4])
result = a[indices]
print(result)
输出:
array([1, 3, 5])
多维数组的操作与此类似,如果有时间,不妨在上述例子上动手试一下,记住,如果使用负整数,索引会从末尾倒着开始哦。
4.3 数组操作
NumPy提供了一些方便的函数来操作数组,包括连接数组、分割数组、改变数组形状和交换数组维度等。
- 连接数组:使用
np.concatenate()
函数沿指定轴连接数组
import numpy as np
a = np.array([[1, 2],
[3, 4]])
b = np.array([[5, 6],
[7, 8]])
# 沿行方向连接数组
result = np.concatenate((a, b), axis=0)
print(result)
输出:
[[1, 2]
[3, 4]
[5, 6]
[7, 8]]
- 分割数组:使用
np.split()
函数将数组分割为多个子数组
import numpy as np
a = np.array([1, 2, 3, 4, 5])
# 将数组分割为3个子数组
result = np.array_split(a, 3)
print(result)
输出:
[array([1, 2]), array([3, 4]), array([5])]
np.array_split()
是 NumPy 中用于将数组拆分成多个子数组的函数。它接受三个参数:数组、拆分的位置或拆分的索引、拆分的轴。当我们拆分多维数组时,又会发生什么呢?
import numpy as np
# 创建一个数组
arr = np.arange(1, 13).reshape(3, 4)
print("原始数组:")
print(arr)
# 对数组进行拆分
sub_arrays = np.array_split(arr, 2, axis=1)
print("\n拆分后的子数组:")
for sub_arr in sub_arrays:
print(sub_arr)
运行这段代码,输出将是:
原始数组:
[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
拆分后的子数组:
[[ 1 2]
[ 5 6]
[ 9 10]]
[[ 3 4]
[ 7 8]
[11 12]]
wahoo,很明显,拆分根据axis参数,只获取二维原始数组(2-D)中的前2列,即在原始二维数组arr的每个元素下标为axis=1的位置停止了。
在这个示例中,我们创建了一个 3 行 4 列的数组 arr
,然后使用 np.array_split(arr, 2, axis=1)
将数组拆分成两个子数组。拆分的结果是一个包含两个数组的列表 sub_arrays
,要注意的是,拆分的轴参数axis是可选的。如果没有提供轴参数,np.array_split()
默认在 0 轴(行)上进行拆分。
- 改变数组形状:使用
np.reshape()
函数改变数组的形状
import numpy as np
a = np.array([[1, 2, 3],
[4, 5, 6]])
# 将数组转换为2x3的形状
result = np.reshape(a, (2, 3))
print(result)
输出:
[[1, 2, 3]
[4, 5, 6]]
- 交换数组维度:使用
np.transpose()
函数交换数组的维度
import numpy as np
a = np.array([[1, 2, 3],
[4, 5, 6]])
# 交换数组的维度
result = np.transpose(a)
print(result)
输出:
[[1, 4]
[2, 5]
[3, 6]]
4.4 ufunc函数
ufunc(universal functions)是一种可以对数组进行元素级运算的函数。NumPy提供了许多ufunc函数,如np.add()
、np.subtract()
、np.multiply()
和np.divide()
等。以下是一个简单的示例:
import numpy as np
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
# 对数组进行元素级加法运算
result = np.add(a, b)
print(result)
输出:
[5, 7, 9]
4.5 矩阵运算
NumPy支持矩阵运算,可以使用np.dot()
函数计算两个数组的矩阵乘法。另外,np.linalg
模块提供了一些常用的线性代数函数,如计算逆矩阵、解线性方程组、计算特征值和特征向量等。以下是一个简单的例子:
import numpy as np
a = np.array([[1, 2],
[3, 4]])
b = np.array([[5, 6],
[7, 8]])
# 计算两个数组的矩阵乘法
result = np.dot(a, b)
print(result)
输出:
[[19, 22]
[43, 50]])
4.6 数组的高级排序
除了常规的排序方法外,NumPy还提供了一些高级的排序技巧。np.lexsort()
函数可以根据键的组合对多个数组进行排序。np.argsort()
函数返回数组排序后的索引,而不是排序后的实际值。以下是一个简单的示例:
import numpy as np
a = np.array([3, 1, 2])
b = np.array([5, 4, 6])
# 根据a和b的值对数组进行排序
indices = np.lexsort((b, a))
sorted_array = a[indices]
print(sorted_array)
输出:
[1, 2, 3]
np.lexsort
函数是 NumPy 中用于执行间接排序的函数。它将根据给定的键序列对数组进行排序,并返回排序后的索引。
具体来说,lexsort
函数使用键序列的最后一个键进行排序,然后使用倒数第二个键进行排序,以此类推,直到使用第一个键进行排序。这样,最终得到的索引序列将使数组按照键序列逐级排序。
让我们通过一个示例来演示 lexsort
函数的用法:
import numpy as np
# 创建一个包含姓名的字符串数组,
names = np.array(['Alice', 'Bob', 'Charlie', 'David'])
# 创建一个二维数组,分别代表上述学生的语文、数学、英语成绩
scores = np.array([[70, 85, 90],
[60, 75, 80],
[80, 90, 85],
[75, 80, 70]])
# 使用 lexsort 对数组进行排序、按
sorted_indices = np.lexsort((scores[:, 1], scores[:, 2], scores[:, 0]))
# 根据排序后的索引序列获取排序后的数组和姓名
sorted_scores = scores[sorted_indices]
sorted_names = names[sorted_indices]
print("Sorted Scores:")
print(sorted_scores)
print("\nSorted Names:")
print(sorted_names)
输出结果为:
Sorted Scores:
[[60 75 80]
[70 85 90]
[75 80 70]
[80 90 85]]
Sorted Names:
['Bob' 'Alice' 'David' 'Charlie']
在上面的示例中,我们使用 lexsort
函数根据每个学生的成绩(先按照数学成绩排序,然后按照英语成绩排序,最后按照语文成绩排序)对学生的记录进行排序。最后,我们根据排序后的索引序列获取了排序后的数组和姓名。
5. 总结
NumPy是Python科学计算的核心库之一,广泛用于数据处理、统计分析和数值计算。
NumPy的高级用法能够提高代码的灵活性和效率,让我们更方便地处理不同形状的数组、获取特定位置的元素,并对数组进行各种操作。通过学习以上几个高级用法,我们可以更好地利用NumPy进行科学计算和数据处理。希望本教程对您有所帮助,更多高级用法请参考NumPy官方文档。
[…] 本文将结合我们上一篇教程(Python基础教程:NumPy库的使用)中提及的NumPy生成样例数据,以便我们用于创建各种类型的图形。以下是一个高级教程,其中包含多个例子和一些高级用法。 […]