numpy进阶之广播、切片、索引、迭代

在这一节中,我们将学习NumPy数组的广播机制,它是一种非常强大和灵活的特性,可以让你对不同形状的数组进行算术运算。
广播机制的基本思想是,当你对两个数组进行算术运算时,如果它们的形状不匹配,NumPy会自动将它们扩展到相同的形状,然后再进行运算。这样可以避免创建大量的临时数组,提高计算效率和内存利用率。
要使用广播机制,你需要遵循以下两条规则:
规则一:如果两个数组的维度不同,那么较低维度的数组会在最左边补1,直到两个数组的维度相同。
规则二:如果两个数组在某个维度上的长度不同,且其中一个数组在该维度上的长度为1,那么该数组会在该维度上重复自身,直到两个数组在该维度上的长度相同。
例如,假设我们有以下两个数组:
当我们对它们进行加法运算时:
NumPy会先根据规则一,将a扩展为(1, 3)的形状:
然后根据规则二,将a在第一个维度上重复自身,直到与b的形状相同:
最后再对两个数组进行逐元素的加法运算:
这样,我们就得到了正确的结果。你可以使用np.broadcast_to()函数来查看广播后的数组:
你也可以使用np.broadcast_arrays()函数来同时查看两个数组广播后的结果:
请注意,广播机制并不会真正地创建新的数组,而是使用视图(view)来节省内存空间。视图是一个指向原始数组数据的引用,它可以改变数组的形状、步长和数据类型等属性,但不会改变原始数据本身。你可以使用np.may_share_memory()函数来检查两个数组是否共享内存空间:
这样,你就完成了NumPy数组广播机制的基本用法。接下来,我们将学习NumPy数组的切片、索引和迭代
在上一节中,我们学习了NumPy数组的广播机制,它可以让你对不同形状的数组进行算术运算。在这一节中,我们将学习NumPy数组的切片、索引和迭代,它们可以让你访问和修改数组中的任意元素或子数组。
切片(slicing)是一种从数组中提取一部分元素的方法,它使用冒号(:)来指定起始、终止和步长(可选)的位置。例如,假设我们有以下数组:
当我们对它进行切片时:
我们得到以下结果:
请注意,切片操作返回的是原始数组的一个视图(view),而不是一个新的数组。这意味着,如果你修改了切片后的数组,原始数组也会跟着改变。例如:
如果你想要得到一个新的数组,而不是一个视图,你可以使用np.copy()函数来复制切片后的数组:
索引(indexing)是一种从数组中提取单个或多个元素的方法,它使用方括号([])来指定元素的位置。NumPy支持多种索引方式,包括基本索引、整数索引、布尔索引等。例如,假设我们有以下数组:
当我们对它进行基本索引时:
当我们对它进行整数索引时:
当我们对它进行布尔索引时:
请注意,索引操作返回的是原始数组的一个副本(copy),而不是一个视图。这意味着,如果你修改了索引后的数组,原始数组不会跟着改变。例如:
迭代(iteration)是一种遍历数组中的所有元素的方法,它使用for循环来实现。NumPy数组的迭代是按照第一个轴(axis)的顺序进行的,也就是说,如果数组是多维的,那么每次迭代的元素是一个子数组。例如,假设我们有以下数组:
当我们对它进行迭代时:
如果我们想要迭代每个元素,而不是每个子数组,我们可以使用np.nditer()函数来实现:
请注意,np.nditer()函数返回的是原始数组的一个视图,而不是一个副本。这意味着,如果你修改了迭代后的元素,原始数组也会跟着改变。例如:
这样,你就完成了NumPy数组切片、索引和迭代的基本用法。接下来,我们将学习NumPy数组的拼接、分割和重塑,请继续关注我的教程!