Python Numpy广播机制

1. 广播 broadcast是用来干什么的

首先,广播针对的运算是element wise类型的运算

element wise元素对元素类型的运算,这些运算的例子如下,在数学定义上要求必须满足相同位置的元素能一一对应,即相应维度的长度要相等/对齐(以下统称对齐)。

算数运算:+, -, *, /, //, %, divmod(), ** or pow(), <<, >>, &, ^, |

比较运算:==, <, >, <=, >=, !=

numpy中维度的对应顺序是倒着对应,两个数组倒数第一个维度相互对应,接着是倒数第二维,如此类推。element-wise的运算,当两个数组总维度不相同时,广播界定了是否能运算,能运算的话该按什么规则运算,厘清了这个场景下的计算规则问题。

例如下面的a和c对应维度对齐,但是总维度不同,该怎么算

"""
两个n-d数组维度相同时,element-wise运算怎么算很清晰
"""
a=np.random.randint(10, size=[2,5])
b=np.random.randint(10, size=[2,5])
(a+b).shape
Out: (2, 5)

"""
当两个n-d数组维度不相同,但看起来又“像能运算”,广播规则定义了该怎么计算
"""
c=np.random.randint(20, size=[2,2,5])
(a+c).shape
Out: (2, 2, 5)    #广播定义了结果数组该怎么算出来

当两个n-d数组对应维度不对齐时,广播提供了一种处理规则:

在不对齐维度上,长度较短的自动做值复制来扩充长度使得两个数组在该维度对齐,能进行合法运算

(这种便利性是为了避免用户代码使用for循环操作数组的低效,自动扩充只是逻辑上的效果,实际上内部实现时是通过设置数组元素计算的step size为0实现的)

广播处理只对如下情况起作用:两个n-d数组,数组对应维度一个长度为m1=1,另一个长度m2>1,即 1 vs M的情况  (两个长度相等不用广播直接算)

广播内容:长度为1的维度会复制扩充为M个,这个维度完成对齐,接着重复检查上一层维度,如此反复,直至所有维度都检查完。

其他情况:当两个数组形状不是这种情况时(即此时相应维度一个数组长度m1>1,另一个长度m2>1,且m1≠m2),pyton直接报错,即此时不能运算,没有广播

如下图的例子,

1) 向量和标量运算,标量自动复制扩充为向量

2)矩阵和向量运算,向量在没对齐的维度自动复制扩充为矩阵

3)两个矩阵在两个维度上都不对齐,且都能广播,在每个维度上分别复制扩充

 

2. 例子

import numpy as np

a = np.array(
       [[0, 1],
       [2, 3],
       [4, 5]])

b = np.array([10,20])

c = np.array([0, 1, 2])

"""
1. element-wise 运算,维度对应关系
b的第0维和a的第1维对齐(维度倒着对齐)
b重复和a的每行运算,输入结果为3*2维
"""
b*a
array([[  0,  20],
       [ 20,  60],
       [ 40, 100]])

"""
1.1 相应维度不对齐,并且长度都不为1,非法
"""
c*a
ValueError: operands could not be broadcast together with shapes (3,) (3,2) 

#c = np.array([0, 1, 2])
d=np.array([[10],[20],[30]])

"""
1.2 相应维度可广播
c在行方向复制扩充,d在列方向
"""
d+c
array([[10, 11, 12],
       [20, 21, 22],
       [30, 31, 32]])

"""
2.1 非element-wise运算,按运算定义来计算,基础对应维度上不适用广播
    如果基础对应维度不对齐,会直接报错
"""
np.dot(d,c)  
ValueError: shapes (3,1) and (3,) not aligned: 1 (dim 1) != 3 (dim 0)
#np.dot(c,d)是合法的

"""
2.2 非element-wise运算
    基础维度合法对齐时,在更高维度上是element-wise对应的(以基础对应块为单位),会适用广播规则
"""
a=np.random.randint(24,size=[2,3,4])
b=np.random.randint(12,size=[4,2])
np.dot(a,b).shape    #能合法进行运算
Out[111]: (2, 3, 2)

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值