首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

numpy的广播机制

NumPy是Python语言的一个扩充程序库。支持高级大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。NumPy的核心功能是"ndarray"(即n-dimensional array,多维数组)数据结构。这是一个表示多维度、同质并且固定大小的数组对象。

最近学习deep learning课程,涉及NumPy中的广播机制,因此参考NumPy的官方文档中Broadcasting部分,了解了这部分的知识,由于原文是英文的,所以我结合自己的想法和理解对该部分文档进行翻译。第一次翻译,难免疏漏,如果有疑问可以查看官方文档,并在留言板留言指正——

(英文文档详见https://docs.scipy.org/doc/numpy-1.13.0/user/basics.broadcasting.html)

Broadcasting(广播)

广播这个术语描述了NumPy在四则运算时如何处理具有不同形状(shape)的数组。受到一定的约束,较小的矩阵可以在较大的矩阵上进行“广播”,这样他们可以有相兼容的形状(shape)。广播提供了一种数组向量化的方法,使Python不会出现在C语言中循环操作(耗时低效)。这种方法不需要做无用的数据复制操作,这通常可以得到高效的算法实现。然而,由于广播会导致低效的内存使用而拖慢计算速度,因此在某些情况广播可能是一种不好的想法。

NumPy运算通常是基于成对的数组之间元素逐个之间的运算。在最简单的情况中,两个数组必须有相同的形状(shape),例如:

>>>a = np.array([1.0,2.0,3.0])

>>>b = np.array([2.0,2.0,2.0])

>>>a * b

array([2.,4.,6.])

NumPy的广播机制放宽了对数组形状的限制,最简单的广播例子是一个数组和一个标量进行乘法运算:

>>>a = np.array([1.0,2.0,3.0])

>>>b =2.0

>>>a * b

array([2.,4.,6.])

这个结果等同于前面那个例子中当是数组的效果。我们可以认为,在四则运算中标量可以拉伸为具有和相同形状的数组。中的新元素是将原有的标量元素进行简单复制。拉伸的比喻仅仅是概念上的。NumPy是足够聪明的,它实际上并不用对原值进行复制,因此广播的运算能够在内存使用和计算上尽可能地高效。

在第二个例子中的代码比第一个例子高效的多,因为广播可以在乘法运算中更少的内存(实际是标量而不是数组)。

General Broadcasting Rules(广播的基本规则)

当两个数组进行运算,NumPy会按元素(element-wise)比较他们的形状。它从后面的维度开始,并不断向前。当满足以下任一条件,两个维度兼容:

他们相等,或者

其中一个是1。

若以上条件都不符合,则会抛出异常ValueError: frames are not aligned,这个异常表示数组维度不兼容。结果数组的尺寸与输入数组的各维度最大尺寸相同。

数组不需要拥有一样的维度。比如,你有一组的RGB值数组,并且想要按不同的值缩放图像中的每种颜色,则可以将该图像乘以一个具有3个值的一维数组。将两个数组的各维度尺寸展开,从后往前匹配,如果满足了上面的两个条件,表明它们是兼容的:

Image(3darray):256x256x3

Scale(1darray):3

Result(3darray):256x256x3

当其中任何一个数组维度是1,那么剩下那个数组的维度(不为1)将作为结果的维度。换句话说,尺寸是1的维度将被拉伸或者“复制”成与另一个数组维度相匹配。

在以下的例子中,A和B两个数组中尺寸为1的维度在广播的过程中都被拉伸为更大的尺寸:

A(4darray):8x1x6x1

B(3darray):7x1x5

Result(4darray):8x7x6x5

这里还有一些例子:

A(2darray):5x4

B(1darray):1

Result(2darray):5x4

A(2darray):5x4

B(1darray):4

Result(2darray):5x4

A(3darray):15x3x5

B(3darray):15x1x5

Result(3darray):15x3x5

A(3darray):15x3x5

B(2darray):3x5

Result(3darray):15x3x5

A(3darray):15x3x5

B(2darray):3x1

Result(3darray):15x3x5

以下例子是不能广播的:

实际应用广播的例子:

广播提供了一种方便计算两个数组外积(或者任何其他外部运算)的方法。以下例子展示了两个一维数组的外加运算:

这里的newaxis操作向 a 中插入新的一维,使 a 成为一个二维的的数组。数组 b 的形状为一维结合的 数组a,最后产生一个的二维数组。

感兴趣的同学可以实际动手敲敲代码,这样对广播机制了解得更加透彻。

peace

原创第12/100篇

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180309G06WA300?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券