什么是Broadcasting

2018-12-09 11:17 更新

Broadcasting

术语 Broadcasting 描述了在算术运算中 numpy 如何处理不同形状的数组.在受到某些约束的情况下,较小的数组在较大的数组上“broadcasting”,以便它们具有兼容的形状.broadcasting 提供了一种向量化数组操作的方法,使循环发生在 C 而不是 Python 中.这样做不会造成不必要的数据副本,通常会导致高效的算法实现.但是,在有些情况下,broadcasting 是一个坏主意,因为它会导致内存使用效率低下,从而减慢计算速度.

NumPy 操作通常是在每个元素的基础上在数组对上完成的.在最简单的情况下,两个数组必须具有完全相同的形状,如下例所示:

>>> 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 的 broadcasting 规则放松了这个约束.最简单的 broadcasting 示例是在一个操作中组合一个数组和一个标量值时发生的:

>>> a = np.array([1.0, 2.0, 3.0])
>>> b = 2.0
>>> a * b
array([ 2.,  4.,  6.])

这个结果等同于前面的例子,其中 b 是一个数组.我们可以认为标量 b 在算术运算过程中被拉伸成与 a 形状相同的数组,b 中的新元素只是原始标量的副本.拉伸的比喻只是概念上的.NumPy 足够聪明,可以使用原始标量值,而不需要实际制作副本,因此 broadcasting 操作尽可能具有记忆效率和计算效率.

第二个例子中的代码比第一个例子中的代码效率更高,因为在乘法(b是一个标量而不是一个数组)中,广播移动的内存较少.

一般broadcasting规则

在两个数组上操作时,NumPy 按照元素比较它们的形状.它从尾随的维度开始,并朝着前进的方向前进.两个维度是兼容的:

  1. 他们是相等的;
  2. 其中有一个是1

如果不满足这些条件, 则会引发异常,ValueError: frames are not aligned,表明数组具有不兼容的形状.结果数组的大小是沿输入数组的每个维度的最大大小.

数组不需要有相同数量的维度.例如,如果您有一个 256x256x3的 RGB 值的数组,并且您想通过不同的值缩放图像中的每个颜色,则可以将图像乘以一个具有3个值的一维数组.根据 broadcasting 规则排列这些数组尾随轴的大小,表明它们是兼容的:

Image  (3d array): 256 x 256 x 3
Scale  (1d array):             3
Result (3d array): 256 x 256 x 3

当比较的任何一个维度时,使用另一个维度.换句话说,维度为1的维度被拉伸或“复制”以匹配另一维度.

在以下示例中,在 broadcasting 操作期间A,B数组都具有长度为1的轴,这些轴在广播操作期间展开为较大的大小:

A      (4d array):  8 x 1 x 6 x 1
B      (3d array):      7 x 1 x 5
Result (4d array):  8 x 7 x 6 x 5

以下是一些例子:

A      (2d array):  5 x 4
B      (1d array):      1
Result (2d array):  5 x 4

A      (2d array):  5 x 4
B      (1d array):      4
Result (2d array):  5 x 4

A      (3d array):  15 x 3 x 5
B      (3d array):  15 x 1 x 5
Result (3d array):  15 x 3 x 5

A      (3d array):  15 x 3 x 5
B      (2d array):       3 x 5
Result (3d array):  15 x 3 x 5

A      (3d array):  15 x 3 x 5
B      (2d array):       3 x 1
Result (3d array):  15 x 3 x 5

以下是不能 broadcasting 的形状的示例:

A      (1d array):  3
B      (1d array):  4 # trailing dimensions do not match

A      (2d array):      2 x 1
B      (3d array):  8 x 4 x 3 # second from last dimensions mismatched

 broadcasting 实践中的一个例子:

>>> x = np.arange(4)
>>> xx = x.reshape(4,1)
>>> y = np.ones(5)
>>> z = np.ones((3,4))

>>> x.shape
(4,)

>>> y.shape
(5,)

>>> x + y
<type 'exceptions.ValueError'>: shape mismatch: objects cannot be broadcast to a single shape

>>> xx.shape
(4, 1)

>>> y.shape
(5,)

>>> (xx + y).shape
(4, 5)

>>> xx + y
array([[ 1.,  1.,  1.,  1.,  1.],
       [ 2.,  2.,  2.,  2.,  2.],
       [ 3.,  3.,  3.,  3.,  3.],
       [ 4.,  4.,  4.,  4.,  4.]])

>>> x.shape
(4,)

>>> z.shape
(3, 4)

>>> (x + z).shape
(3, 4)

>>> x + z
array([[ 1.,  2.,  3.,  4.],
       [ 1.,  2.,  3.,  4.],
       [ 1.,  2.,  3.,  4.]])

 broadcasting 为两个数组的外部产品(或任何其他外部操作)提供了一种方便的方法.以下示例显示了两个一维数组的外部附加操作:

>>> a = np.array([0.0, 10.0, 20.0, 30.0])
>>> b = np.array([1.0, 2.0, 3.0])
>>> a[:, np.newaxis] + b
array([[  1.,   2.,   3.],
       [ 11.,  12.,  13.],
       [ 21.,  22.,  23.],
       [ 31.,  32.,  33.]])

这里的 newaxis 索引操作符将一个新的轴插入到 a 中,使其成为一个二维 4x1 数组.将 4x1 数组与 b 组合在一起,它有形状(3,),生成一个4x3数组.

以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy