在本文中,我们将探索著名且有用的Python数据分析库NumPy的强大功能,其中主要用于存储元素和执行操作的数据结构是多维数组。我们将看到这个动态库如何使复杂的数学任务在空间和时间复杂度方面更加高效。此外,还可以看到如何通过轻松的操作使数据操作和转换变得更加容易。
什么是NumPy?
Numpy,Scipy和Matplotlib是用于数据科学项目的Python库,它们提供类似MATLAB的功能。
主要特点如下:
- 类型化的多维数组(矩阵)
- 快速数值计算(矩阵运算)
- 高级数学函数
NumPy代表Numerical Python,是高性能计算和数据分析所需的基本包。NumPy在Python中进行数值计算是必需的,因为它专为大型数据数组的效率而设计。
创建NumPy数组的不同方法
在开始对NumPy数组进行操作之前,我们的首要目标是根据问题描述根据需求创建NumPy数组。
有多种方法可以创建NumPy数组。下面介绍了一些常见且实用的方法:
情况1:使用np.ones方法创建一个全为1的数组:
如果我们只需要创建一个全为“1”的数组,可以使用这种方法。
np.ones((3,5), dtype=np.float32)
#输出
[[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]
情况2:使用np.zeros方法创建一个全为0的数组:
如果我们只需要创建一个全为“0”的数组,可以使用这种方法。
np.zeros((6,2), dtype=np.int8)
#输出
[[0 0]
[0 0]
[0 0]
[0 0]
[0 0]
[0 0]]
情况3:使用np.arange方法:
如果要创建一个按照序列排列的元素数组,可以使用这种方法。
np.arange(1334,1338)
#输出
[1334 1335 1336 1337]
情况4:使用np.concatenate方法:
当您需要的数组是一个或多个数组的组合时,可以使用这种方法。
A = np.ones((2,3))
B = np.zeros((4,3))
C = np.concatenate([A, B])
#输出
[[1. 1. 1.]
[1. 1. 1.]
[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]
情况5:使用np.random.random方法:
当需要创建具有随机值的数组时,可以使用这种方法。
np.random.random((2,3))
#输出
[[0.30512345 0.10055724 0.89505387]
[0.36219316 0.593805 0.7643694 ]]
NumPy数组操作
让我们通过一个示例来讨论NumPy数组的基本属性:
代码:
a = numpy.array([[1,2,3],[4,5,6]],dtype=numpy.float32)
#数组的维度、形状和数据类型
print (a.ndim, a.shape, a.dtype)
输出:
2 (2, 3) float32
根据以上代码,我们总结如下:
- 数组可以有任意维度的正整数,包括零(对应标量值)。
- 数组是有类型的,可以具有数据类型,如 np.uint8,np.int64,np.float32,np.float64。
- 数组是密集的。数组的每个元素都存在且具有相同的类型。
代码:
# 数组重塑
a = numpy.array([1,2,3,4,5,6])
a = a.reshape(3,2)
#输出:
[[1 2]
[3 4]
[5 6]]
a = a.reshape(2,-1)
#输出:
[[1 2 3]
[4 5 6]]
a = a.ravel()
#输出:
[1 2 3 4 5 6]
需要记住的重要点:
- 重塑操作后,数组中的元素总数不能改变。
- 可以使用-1来推断轴的形状。
- 默认情况下,它以行优先格式存储元素,而在 MATLAB 中则是列优先。
Numpy 数组广播
广播允许在不同形状的数组上执行操作,只要它们是兼容的。较小数组的维度会被虚拟扩展以匹配较大数组的维度。
代码:
# 数组广播
a = numpy.array([[1, 2], [3, 4], [5, 6]])
b = numpy.array([10, 20])
c = a + b # 将数组 'b' 广播以匹配数组 'a' 的维度
这个例子涉及一个二维的NumPy数组 ‘a’,维度为 (3, 2),和一个一维数组 ‘b’,形状为 (2)。广播允许操作 ‘a + b’ 在第二维度上虚拟扩展 ‘b’ 以匹配 ‘a’,从而实现 ‘a’ 和扩展后的 ‘b’ 之间的逐元素相加。
数组索引和切片
- 切片是视图。对切片的写入会覆盖原始数组。
- 列表或布尔数组也可以用作索引。
- Python 索引语法:
开始索引 : 结束索引 : 步长
代码:
a = list(range(10))
# 前 3 个元素
a[:3] # 索引 0, 1, 2
# 后 3 个元素
a[-3:] # 索引 7, 8, 9
# 索引 3, 5, 7
a[3:8:2]
# 索引 4, 3, 2(这个有点棘手)
a[4:1:-1]
如您所知,图像也可以被视为多维数组。因此,切片也可以用于对图像执行一些数学操作。下面列举了一些重要和高级的示例,以增加您的理解:
# 选择除了边界像素之外的所有像素
pixel_matrix[1:-1,1:-1]
# 交换通道顺序
pixel_matrix = pixel_matrix[:,:,::-1]
# 将暗像素设置为黑色
pixel_matrix[pixel_matrix<10] = 0
# 选择第二行和第四行
pixel_matrix[[1,3], :]
数组聚合和约简
现在,我们将开始对numpy数组进行聚合操作。通常,可以执行以下操作:
- 找到数组中所有元素的和和乘积。
- 找到数组中的最大和最小元素。
- 找到数组中特定元素的数量。
- 我们还可以使用线性代数模块找到其他参数,包括矩阵行列式、矩阵迹、矩阵特征值和特征向量等。
让我们开始用例子讨论每个功能:
Case-1:数组中所有元素的代数和
array_1 = numpy.array([[1,2,3], [4,5,6]])
print(array_1.sum())
#输出:
21
Case-2:数组中的最大元素
array_1 = numpy.array([[1,2,3], [4,5,6]])
print(array_1.max())
#输出:
6
Case-3:数组中的最小元素
array_1 = numpy.array([[1,2,3], [4,5,6]])
print(array_1.min())
#输出:
1
Case-4:数组中最大元素所在的位置/索引
array_1 = numpy.array([[1,2,3], [4,5,6]])
print(array_1.argmax())
#输出:
5
Case-5:数组中最小元素所在的位置/索引
array_1 = numpy.array([[1,2,3], [4,5,6]])
print(array_1.argmin())
#输出:
0
在找到位置时,可以观察到它将任何多维数组视为一个一维数组,然后进行计算。
Case-6:数组中所有元素的平均值
array_1 = numpy.array([[1,2,3], [4,5,6]])
print(array_1.mean())
#输出:
3.5
Case-7:两个多维数组的点积/标量积
array_1 = numpy.array([[1,2], [4,5]])
array_2 = numpy.array([[1,-1,2], [3,7,-2]])
t = array_1.dot(array_2)
print(t)
#输出:
[[ 7 13 -2]
[19 31 -2]]
NumPy数组中的向量化
向量化可以在整个数组上执行操作,而不是通过单个元素循环。它利用优化的低级例程,从而实现更快速和更简洁的代码。
代码:
a = numpy.array([1, 2, 3, 4, 5])
b = numpy.array([10, 20, 30, 40, 50])
c = a + b # 无需显式循环的逐元素相加
根据上面的例子,可以看到创建了两个名为’a’和’b’的NumPy数组。在执行 ‘a + b’ 操作时,我们使用向量化概念在数组之间执行逐元素相加,结果是一个新的数组 ‘c’,其中包含来自 ‘a’ 和 ‘b’ 的对应元素的和。因此,由于逐元素操作,程序避免了运行显式循环,并利用优化的例程进行高效的计算。
数组连接
Case-1:假设您有两个或更多数组要使用 concatenate 函数进行连接,您必须连接数组的元组。
代码:
# 使用 concatenate 函数按行连接 2 个或多个数组
numpy_array_1 = numpy.array([1,2,3])
numpy_array_2 = numpy.array([4,5,6])
numpy_array_3 = numpy.array([7,8,9])
array_concatenate = numpy.concatenate((numpy_array_1, numpy_array_2, numpy_array_3))
print(array_concatenate)
#输出:
[1 2 3 4 5 6 7 8 9]
Case 2:假设您有一个具有多个维度的数组;那么,要连接数组,您必须指定要连接的轴。否则,默认将沿第一个维度执行连接。
代码:
# 使用concatenate函数按列连接两个或多个数组
array_1 = numpy.array([[1,2,3], [4,5,6]])
array_2 = numpy.array([[7,8,9], [10, 11, 12]])
array_concatenate = numpy.concatenate((array_1, array_2), axis=1)
print(array_concatenate)
#输出:
[[ 1 2 3 7 8 9]
[ 4 5 6 10 11 12]]
数学函数和通用函数
这些通用函数也被称为ufuncs。这些函数执行逐元素操作。例如:
- np.exp
- np.sqrt
- np.sin
- np.cos
- np.isnan
代码:
A = np.array([1,4,9,16,25])
B = np.sqrt(A)
#输出
[1. 2. 3. 4. 5.]
性能比较
在进行数值计算时,如果有大量的计算,Python需要更多的时间。如果我们取一个形状为1000 x 1000的矩阵进行矩阵乘法运算,Python和numpy所需的时间分别为:
- Python三重循环需要超过10分钟
- Numpy需要约0.03秒
因此,从上面的例子中我们可以看出,numpy比标准的Python需要更少的时间,因此在数据科学相关的实际项目中,numpy可以减少延迟,因为这些项目通常需要处理大量的数据。
总结
在本文中,我们讨论了numpy数组。因此,为了总结我们的讨论,让我们总结一下numpy相对于Python的优势:
- Numpy具有面向数组的计算。
- Numpy高效地实现了多维数组。
- Numpy主要用于科学计算。
- Numpy包含了标准的数学函数,可以在数组上进行快速计算而不需要循环。
- Numpy具有内置的线性代数和随机数生成模块,可以处理和傅里叶变换能力。
- Numpy还包含用于将数组读写到磁盘和处理内存映射文件的工具。
Aryan Garg是一名电气工程学士学位的学生,目前正在本科的最后一年。他对Web开发和机器学习领域有兴趣。他一直追求这个兴趣,并渴望在这些方向上有更多的工作机会。