美文网首页
5-Numpy数组广播

5-Numpy数组广播

作者: 勃列日涅夫 | 来源:发表于2020-03-18 14:14 被阅读0次

    广播

    广播允许在不同大小的数组上执行加减乘除的二进制运算 例如

    In [1]: import numpy as np
    
    In [2]: a = np.array([0, 1, 2])
       ...: b = np.array([5, 5, 5])
    
    In [3]: a*b
    Out[3]: array([ 0,  5, 10])
    

    NumPy广播的优点是在复制值得过程中没有占用额外得空间,但是在我们考虑广播时,它是一种有用的思维模型。
    例如如下对三维数组数值扩展

    In [8]: m=np.ones((3,3))
    In [9]: 3+m
    Out[9]: 
    array([[4., 4., 4.],
           [4., 4., 4.],
           [4., 4., 4.]])
    

    两个数组相加扩展

    In [17]: a = np.arange(3)
        ...: b = np.arange(3)[:, np.newaxis]
        ...: print(a)
        ...: print(b)
    [0 1 2]
    [[0]   
     [1]   
     [2]]  
    # 两个数组相加(注意数组非矩阵)
    In [18]:a + b
    Out[18]: 
    array([[0, 1, 2],
           [1, 2, 3],
           [2, 3, 4]])
    

    就像我们拉伸或广播一个值以匹配另一个值的形状一样,这里拉伸了a和b以匹配一个通用形状,结果是一个二维数组!
    下图显示了这些示例的几何形状(可以在附录中找到生成该图的代码,并改编自astroML文档中发布的源)。
    [图片上传失败...(image-d405c3-1584512066939)]

    这些图中额外的内存实际上并没有在操作过程中分配.这里时为了从概念理解。

    广播得规则

    NumPy中的广播遵循一套严格的规则来确定两个数组之间的交互:

    规则1:如果两个数组的维数不同,则维数较少的数组的形状将在其前(左侧)填充。
    规则2:如果两个数组的形状在任何维度上都不匹配,则将在该维度上形状等于1的数组拉伸以匹配其他形状。
    规则3:如果尺寸在任何维度上都不相同,且都不等于1,则会引发错误。
    

    广播示例1

    下面详细来说明

    In [23]: M = np.ones((2, 3))
      ...: a = np.arange(3)
    
    • 首先创建得两个数组,M 为2行3列的二维数组,a为一个1行的一维数组
    1. 首先根据规则1,我们看到数组a的维数较少,因此我们在数组的左侧填充了1维使其成为和M相同维度的二维数组:

      M.shape -> (2, 3)
      a.shape -> (1, 3)

    2. 根据规则2,我们现在看到维度相同,但是尺寸不一致,因此我们拉伸该维度以使其匹配:

      M.shape -> (2, 3)
      a.shape -> (2, 3)
      最终我们通过拉伸变换使其形状匹配,我们看到最终形状将是(2,3):

    In [23]: M = np.ones((2, 3))
        ...: a = np.arange(3)
    In [24]: M+a
    Out[24]: 
    array([[1., 2., 3.],
           [1., 2., 3.]])
    

    广播示例2

    让我们看下两个数组都需要拉伸变换来适应匹配的

    In [28]: a = np.arange(3).reshape((3, 1))
        ...: b = np.arange(3)
    
    1. 首先我们创造一个,3*1的二维数组和一个一维数组

      a.shape = (3, 1)
      b.shape = (3,)

    2. 规则1说我们必须填充b的形状使其形成二维数组(1行3列):

      a.shape -> (3, 1)
      b.shape -> (1, 3)

    3. 根据规则2,我们将每个升级,以匹配另一个数组的相应大小(都扩展成3*3的数组):

    In [30]: a+b
    Out[30]: 
    array([[0, 1, 2],
           [1, 2, 3],
           [2, 3, 4]])
    

    广播示例3

    我们在看两个不匹配的数组

    In [31]: M = np.ones((3, 2))
        ...: a = np.arange(3)
        
    

    考虑上面a和M,分析简略如下
    首先a M

    M.shape = (3, 2)
    a.shape = (3,)
    

    根据规则一,对a扩展成

    M.shape -> (3, 2)
    a.shape -> (1, 3)
    

    根据规则2,对a 的行扩展

    M.shape -> (3, 2)
    a.shape -> (3, 3)
    

    扩展后我们发现,两者不匹配执行

    In [32]: a+M
    ---------------------------------------------------------------------------
    ValueError                                Traceback (most recent call last)
    <ipython-input-32-60afc280ce5f> in <module>
    

    *此处可能存在的混乱:可以想象通过将a的形状用右边而不是左边的形状填充来使a和M兼容。但这不是广播规则的工作方式!这种灵活性在某些情况下可能有用,但可能会导致歧义。如果想要右侧填充,则可以通过重塑数组来明确地做到这一点(我们将使用《 NumPy数组基础》中引入的np.newaxis关键字):

    # 将a变换 成3*1的数组和M广播
    In [34]: a[:, np.newaxis].shape
    Out[34]: (3, 1)
    
    In [35]: M + a[:, np.newaxis]
    Out[35]: 
    array([[1., 1.],
           [2., 2.],
           [3., 3.]])
    

    *同样除了+ 还可以用于其他函数例如log等

    广播操作练习

    在上一节中,我们看到ufunc允许NumPy用户消除显式编写慢速Python循环的需要。广播扩展了此功能。一个常见的示例是将数据阵列居中时。假设您有一个包含10个观测值的数组,每个观测值包含3个值。,我们将其存储在10×3数组中:

    In [43]: a=np.arange(9).reshape((3,3))
    In [44]: a
    Out[44]:         
    array([[0, 1, 2],
           [3, 4, 5],
           [6, 7, 8]])
    #我们可以使用第一维上的均值合计来计算每个特征的均值:
    In [46]: a.mean(0)
    Out[46]: array([3., 4., 5.])
    

    绘制二维函数

    广播非常有用的一个地方是基于二维函数显示图像。如果我们要定义一个函数z= f(x,y),可以使用广播来计算整个网格中的函数
    这里我们用py代码执行

    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
    import numpy as np
    #我们将使用Matplotlib绘制此二维数组(这些工具将在“密度和轮廓图”中进行全面讨论):
    import matplotlib.pyplot as plt
    x=np.linspace(0,5,50)
    y=np.linspace(0,5,50)[:,np.newaxis]
    z=np.sin(x)**2 + np.cos(6+y*x)*np.cos(x)
    plt.imshow(z, origin='lower', extent=[0, 5, 0, 5],cmap='viridis')
    plt.colorbar();
    plt.show()  #关键的地方
    

    [图片上传失败...(image-8ea90c-1584512066939)]

    相关文章

      网友评论

          本文标题:5-Numpy数组广播

          本文链接:https://www.haomeiwen.com/subject/uggqyhtx.html