您的位置:首页 > 编程语言 > Python开发

Numpy的广播机制

2019-06-18 14:22 330 查看
[code]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:

[code]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.])

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

[code]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),然后按照一一对应的方式计算

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

[code] 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):

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

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

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

 进行如下操作:

[code]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)

[code]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轴上进行复制,如下所示:

[code]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返回的是进行广播后的数组.
 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: