Numpy的广播机制

All input arrays with ndim smaller than the input array of largest ndim, have 1’s prepended to their shapes. 
The size in each dimension of the output shape is the maximum of all the input sizes in that dimension. 
An input can be used in the calculation if its size in a particular dimension either matches the output size in that dimension, or has value exactly 1. 
If an input has a dimension size of 1 in its shape, the first data entry in that dimension will be used for all calculations along that dimension. In other words, the stepping machinery of the ufunc will simply not step along that dimension (the stride will be 0 for that dimension).

让所有输入数组都向其中shape最长的数组看齐,shape中不足的部分都通过在前面加1补齐 
输出数组的shape是输入数组shape的各个轴上的最大值 
如果输入数组的某个轴和输出数组的对应轴的长度相同或者其长度为1时,这个数组能够用来计算,否则出错,当输入数组的某个轴的长度为1时,沿着此轴运算时都用此轴上的第一组值
 

一般情况下,numpy 都是采用一一对应的方式(element-by-element )进行计算

例子1:

from numpy import array 
a = array([1.0,2.0,3.0])
b = array([2.0,2.0,2.0])
a * b
# array([ 2.,  4.,  6.])

当不相等时,则会采用规则对齐:

from numpy import array
a = array([1.0,2.0,3.0])
b = 2.0
a * b
# array([ 2.,  4.,  6.])

a.shape得到的是(3,) b是一个浮点数,如果转换成array,则b.shape是一个(),a的1轴对齐,补齐为1,a.shape(3,1),b对齐,则对齐也为(3,1),然后按照一一对应的方式计算

或许上述例子不是太明确,下面采用一个更加确切的例子说明:

 import numpy as np
 a = np.arange(0, 6).reshape(6, 1)
 a
# array([[ 0], [1], [2], [3], [4], [5]])
 a.shape
# (6, 1)
 b = np.arange(0, 5)
 b.shape
# (5,)
 c = a + b
 print (c)
# [[0 1 2 3 4]
# [1 2 3 4 5]
# [2 3 4 5 6]
# [3 4 5 6 7]
# [4 5 6 7 8]
# [5 6 7 8 9]]

官方的图是这样的:

è¿éåå¾çæè¿°

 

Python 广播
​    当两个数组中每个元素都进行相应的运算的时候,需要两个数组的形状相同,如果形状不同,则使用Python的广播机制进行处理.如下面的例子说明广播是如何操作的.

​    建立一个二维数组,形状是(6,1):

a = np.arange(0, 60, 10).reshape(-1, 1)
a.shape
# (6, 1)
a
'''
array([[ 0],
       [10],
       [20],
       [30],
       [40],
       [50]])
'''

建立一个一维数组b,其形状为(5,):

b = np.arange(0, 5)
b
#array([0, 1, 2, 3, 4])
b.shape
#(5,)

 进行如下操作:

c = a + b
c
'''
array([[ 0,  1,  2,  3,  4],
       [10, 11, 12, 13, 14],
       [20, 21, 22, 23, 24],
       [30, 31, 32, 33, 34],
       [40, 41, 42, 43, 44],
       [50, 51, 52, 53, 54]])
'''
c.shape
# (6, 5)

 由于a和b的维数不同,首先需要让b的shape属性向a对齐,即将b变为(1,5)

b.shape = 1, 5
b.shape
#(1, 5)
b
#array([[0, 1, 2, 3, 4]])

    加法的两个输入数组的属性分别为(6,1)和(1,5),输出数组的各个轴的长度为输入数组各个轴的长度的最大值,则输出数组的属性为(6,5);

​    首先将b在第0轴上进行复制,a在第1轴上进行复制,如下所示:

b = b.repeat(6, axis=0)
b
'''
array([[0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4]])
'''
b.shape
# (6, 5)
a = a.repeat(5, axis=1)
a
'''
array([[ 0,  0,  0,  0,  0],
       [10, 10, 10, 10, 10],
       [20, 20, 20, 20, 20],
       [30, 30, 30, 30, 30],
       [40, 40, 40, 40, 40],
       [50, 50, 50, 50, 50]])
'''
a.shape
# (6, 5)

#上述a和b可以进行相应的运算

注意:numpy内部不会使用repeat进行数据扩展,这样会占用空间,而是使用内部集成的函数进行.

如ogrid和mgrid函数.

ogrid函数创建广播预算用的数组,mgrid返回的是进行广播后的数组.
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值