NumPy之:理解广播
简介
广播描述的是NumPy如何计算不同形状的数组之间的运算。如果是较大的矩阵和较小的矩阵进行运算的话,较小的矩阵就会被广播,从而保证运算的正确进行。
本文将会以具体的例子详细讲解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的广播特性,那么就不必须元素的个数准确对应。
比如,我们可以讲一个数组乘以常量:
a = np.array([1.0, 2.0, 3.0])
>>> b = 2.0
>>> a * b
array([ 2., 4., 6.])
下面的例子和上面的例子是等价的,Numpy会自动将b进行扩展。
NumPy足够聪明,可以使用原始标量值而无需实际制作副本,从而使广播操作尽可能地节省内存并提高计算效率。
第二个示例中的代码比第一个示例中的代码更有效,因为广播在乘法过程中移动的内存更少(b是标量而不是数组)。
广播规则
如果两个数组操作,NumPy会对两个数组的对象进行比较,从最后一个维度开始,如果两个数组的维度满足下面的两个条件,我们就认为这两个数组是兼容的,可以进行运算:
- 维度中的元素个数是相同的
- 其中一个维数是1
如果上面的两个条件不满足的话,就会抛出异常: ValueError: operands could not be broadcast together。
维度中的元素个数是相同的,并不意味着要求两个数组具有相同的维度个数。
比如表示颜色的256x256x3 数组,可以和一个一维的3个元素的数组相乘:
Image (3d array): 256 x 256 x 3
Scale (1d array): 3
Result (3d array): 256 x 256 x 3
相乘的时候,维度中元素个数是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
上面的例子中,第二维的1被拉伸到7,第三维的1被拉伸到6,第四维的1被拉伸到5。
还有更多的例子:
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
下面是不匹配的例子:
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
再举个实际代码的例子:
>>> 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
ValueError: operands could not be broadcast together with shapes (4,) (5,)
>>> 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.]])
广播还提供了一个非常方便的进行两个1维数组进行外部乘积的运算:
>>> 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.]])
其中a[:, np.newaxis] 将1维的数组转换成为4维的数组:
In [230]: a[:, np.newaxis]
Out[230]:
array([[ 0.],
[10.],
[20.],
[30.]])
本文已收录于 http://www.flydean.com/07-python-numpy-broadcasting/
最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!
欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!
NumPy之:理解广播的更多相关文章
- numpy中的广播
目录 广播的引出 广播的原则 数组维度不同,后缘维度的轴长相符 数组维度相同,其中有个轴为1 参考: 广播的引出 numpy两个数组的相加.相减以及相乘都是对应元素之间的操作. import num ...
- numpy中的广播机制
广播的引出 numpy两个数组的相加.相减以及相乘都是对应元素之间的操作. import numpy as np x = np.array([[2,2,3],[1,2,3]]) y = np.arra ...
- Numpy中的广播机制,数组的广播机制(Broadcasting)
这篇文章把numpy中的广播机制讲的十分透彻: https://jakevdp.github.io/PythonDataScienceHandbook/02.05-computation-on-arr ...
- Numpy中的广播原则(机制)
为了了解这个原则,首先我们来看一组例子: # 数组直接对一个数进行加减乘除,产生的结果是数组中的每个元素都会加减乘除这个数. In [12]: import numpy as np In [13]: ...
- numpy中的广播(Broadcasting)
Numpy的Universal functions 中要求输入的数组shape是一致的,当数组的shape不相等的时候,则会使用广播机制,调整数组使得shape一样,满足规则,则可以运算,否则就出错 ...
- numpy.meshgrid()理解
本文的目的是记录meshgrid()的理解过程: step1. 通过一个示例引入创建网格点矩阵; step2. 基于步骤1,说明meshgrid()的作用; step3. 详细解读meshgrid() ...
- 对numpy.meshgrid()理解
一句话解释numpy.meshgrid()——生成网格点坐标矩阵.关键词:网格点,坐标矩阵 网格点是什么?坐标矩阵又是什么鬼?看个图就明白了: 图中,每个交叉点都是网格点,描述这些网格点的坐标的矩阵, ...
- numpy深入理解剖析
http://www.scipy-lectures.org/advanced/advanced_numpy/index.html
- numpy和tensorflow中的广播机制
广播的引出 numpy两个数组的相加.相减以及相乘都是对应元素之间的操作. import numpy as np x = np.array([[2,2,3],[1,2,3]]) y = np.arra ...
随机推荐
- Linux目录,rpm及top,vi命令简记
一次简单的Linux常用操作记录 一.一些Linux目录结构 /bin 存放二进制可执行文件(ls.cat.mkdir等),一些常用的命令一般都在这里. /etc 存放系统管理和配置文件 /home ...
- golang 实现距离幂算法
func main() { var test []Pow var x1 Pow x1.distance = 110 x1.grade = 0.31 var x2 Pow x2.distance = 8 ...
- P1739_表达式括号匹配(JAVA语言)
思路:刚开始想用stack,遇到'('就push,遇到')'就pop,后来发现其实我们只需要用到栈里'('的个数,所以我们用一个变量统计'('的个数就好啦~ 题目描述 假设一个表达式有英文字母(小写) ...
- python2 虚拟环境
1.安装virtualenv pip install virtualenv 2.创建虚拟环境 virtualenv 虚拟环境名称 3.激活虚拟环境 source 虚拟环境目录/bin/activat ...
- C++中的间接宏函数
宏函数对于每个C++程序员都决不陌生,就算是初出茅庐的C++程序员也知道如何定义.使用宏函数. 但是当初学者看到类似于以下这种宏函数嵌套的时候,可能还是会比较嘀咕, #define CONVERT ...
- Shell中的(),{}几种语法用法-单独总结
shell中的(),{}几种语法用法 查看脚本语法是否有错误: bash -n modify_suffix.sh 跟踪执行 sh -x modify_suffix.sh aaa 1. ${var} 2 ...
- 结对作业-stage_1
教学班 罗杰.任建班周五3.4节 gitlab项目地址 Here it is. 成员 周远航(3004) 李辰洋(3477) 结对编程体验 感受 在前期设计时,两人合作可以收集更多资料,提供更多想法, ...
- Java后端进阶-消息中间件
1.分布式事务 MQ分布式消息中间件实战应用 通过控制台就可以定义 二.分布式消息中间件 解决耦合的问题 http内容很繁琐,而且是短连接响应后就会中断 持久化 消息分发 高可用 高可靠
- 2020北航OO第三单元总结
2020北航OO第三单元总结 本单元要求是根据JML规格完善代码,初看是一个简单的代码照搬实现的东西,但最后才发现由于CPU时间的限制,还考察了大量优化策略及数据结构中关于图的知识,是一次非常注重细节 ...
- odoo字段属性列举
罗列一些Odoo中的字段属性,基本包含大部分的属性. 常用字段属性 平平无奇常用字段属性 string:字段的标题,在UI视图标签中使用.它是可选项,如未设置,会通过首字母大写及将空格替换成为下划线来 ...