📜  Python中的NumPy 2(高级)

📅  最后修改于: 2020-04-15 05:12:46             🧑  作者: Mango

Python中的NumPy 设置1(简介)
本文讨论了NumPy中可用的更多高级方法。

  1. 堆叠:几个阵列可以沿着不同的轴堆叠在一起。
    • np.vstack:沿垂直轴堆叠数组。
    • np.hstack:沿水平轴堆叠数组。
    • np.column_stack:将一维数组作为列堆叠到二维数组中。
    • np.concatenate:沿指定轴堆叠数组(轴作为参数传递)。
      import numpy as np
      a = np.array([[1, 2],
                    [3, 4]])
      b = np.array([[5, 6],
                    [7, 8]])
      # 垂直堆叠
      print("垂直堆叠:\n", np.vstack((a, b)))
      # 水平堆叠
      print("\n水平堆叠\n", np.hstack((a, b)))
      c = [5, 6]
      # 堆叠列
      print("\n堆叠列:\n", np.column_stack((a, c)))
      # concatenation方法
      print("\n连接到第二轴:\n", np.concatenate((a, b), 1))
      

      输出:

      垂直堆叠:
       [[1 2]
       [3 4]
       [5 6]
       [7 8]]
      水平堆叠:
       [[1 2 5 6]
       [3 4 7 8]]
      堆叠列:
       [[1 2 5]
       [3 4 6]]
      连接到第二轴:
       [[1 2 5 6]
       [3 4 7 8]]

      2,拆分:对于拆分,我们具有以下功能:

      • np.hsplit:沿水平轴拆分数组。
      • np.vsplit:沿垂直轴拆分数组。
      • np.array_split:沿指定轴拆分数组。
        import numpy as np
        a = np.array([[1, 3, 5, 7, 9, 11],
                      [2, 4, 6, 8, 10, 12]])
        # 水平分割
        print("沿水平轴分为2部分:\n", np.hsplit(a, 2))
        # vertical splitting
        print("\n沿垂直轴分为2部分:\n", np.vsplit(a, 2))

        输出:

        沿水平轴分为2部分:
         [array([[1, 3, 5],
               [2, 4, 6]]), array([[ 7,  9, 11],
               [ 8, 10, 12]])]
        沿垂直轴分为2部分:
         [array([[ 1,  3,  5,  7,  9, 11]]), array([[ 2,  4,  6,  8, 10, 12]])]

        3, broadcast广播:术语broadcast广播描述了NumPy在算术运算期间如何处理具有不同形状的数组。受到某些约束,较小的数组将在较大的数组上“广播”,以便它们具有兼容的形状。广播提供了一种对数组操作进行矢量化的方法,从而使循环在C而不是Python中发生。它无需复制不必要的数据即可完成此操作,通常可以实现高效的算法实现。在某些情况下,广播不是一个好主意,因为广播会导致内存使用效率低下,从而减慢计算速度。
        NumPy操作通常逐个元素完成,这需要两个数组具有完全相同的形状。当数组的形状满足某些约束时,Numpy的广播规则会放宽此约束。
        广播规则:为了进行广播,操作中两个阵列的尾随轴的大小必须相同,或者其中之一必须为1
        让我们看一些例子:

        A(2-D array): 4 x 3
        B(1-D array):     3
        Result      : 4 x 3
        A(4-D array): 7 x 1 x 6 x 1
        B(3-D array):     3 x 1 x 5
        Result      : 7 x 3 x 6 x 5

        最简单的广播示例是在操作中将数组和标量值组合在一起时发生的。
        考虑下面给出的示例:

        import numpy as np
        a = np.array([1.0, 2.0, 3.0])
        # 例子1
        b = 2.0
        print(a * b)
        # 例子2
        c = [2.0, 2.0, 2.0]
        print(a * c)

        输出:

        [2. 4. 6.]
        [2. 4. 6.]

        我们可以认为标量b在算术运算中被拉伸成与a形状相同的数组。如上图所示,b中的新元素只是原始标量的副本。虽然,拉伸类比只是概念上的。
        Numpy足够聪明,可以在不实际制作副本的情况下使用原始标量值,从而使广播操作尽可能地节省内存并提高计算效率。因为示例1在乘法过程中移动的内存较少(b是一个标量,而不是数组),所以与带有一百万个元素数组的Windows 2000上的标准numpy相比,示例2的速度比示例2快10%!
        下图使概念更清晰:

        在上面的示例中,标量b被拉伸为具有与a相同形状的数组,因此这些形状适用于逐元素乘法。
        现在,让我们看一个两个数组都伸展的例子。

        import numpy as np
        a = np.array([0.0, 10.0, 20.0, 30.0])
        b = np.array([0.0, 1.0, 2.0])
        print(a[:, np.newaxis] + b)

        输出:

        [[0. 1. 2.]
         [10. 11. 12.]
         [20. 21. 22.]
         [30. 31. 32.]]


        在某些情况下,广播会拉伸两个数组以形成一个输出数组,该输出数组要大于两个初始数组中的任何一个。

        使用日期时间: Numpy具有核心数组数据类型,其本身支持日期时间功能。数据类型称为“ datetime64″,之所以这样命名是因为Python中包含的datetime库已经采用了“ datetime”名称。
        考虑以下示例中的一些示例:

        import numpy as np
        # 创建一个日期
        today = np.datetime64('2017-02-12')
        print("日期是:", today)
        print("年是:", np.datetime64(today, 'Y'))
        # 在一个月内创建日期数组
        dates = np.arange('2017-02', '2017-03', dtype='datetime64[D]')
        print("\n二月的日期, 2017:\n", dates)
        print("今天是二月:", today in dates)
        # 日期的算术运算
        dur = np.datetime64('2017-05-22') - np.datetime64('2016-05-22')
        print("\n天数:", dur)
        print("周数:", np.timedelta64(dur, 'W'))
        # 排序日期
        a = np.array(['2017-02-12', '2016-10-13', '2019-05-22'], dtype='datetime64')
        print("\n日期排序:", np.sort(a))

        输出:

        日期是: 2017-02-12
        年是: 2017
        二月的日期, 2017:
         ['2017-02-01' '2017-02-02' '2017-02-03' '2017-02-04' '2017-02-05'
         '2017-02-06' '2017-02-07' '2017-02-08' '2017-02-09' '2017-02-10'
         '2017-02-11' '2017-02-12' '2017-02-13' '2017-02-14' '2017-02-15'
         '2017-02-16' '2017-02-17' '2017-02-18' '2017-02-19' '2017-02-20'
         '2017-02-21' '2017-02-22' '2017-02-23' '2017-02-24' '2017-02-25'
         '2017-02-26' '2017-02-27' '2017-02-28']
        今天是二月: True
        天数: 365 days
        周数: 52 weeks
        日期排序: ['2016-10-13' '2017-02-12' '2019-05-22']

        5,NumPy中的线性代数:NumPy的线性代数模块提供了将线性代数应用于任何numpy数组的多种方法。
        你可以找到:

        • 数组的rank,行列式,轨迹等。
        • 矩阵的特征值
        • 矩阵和向量乘积(点,内,外等乘积),矩阵求幂
        • 解决线性或张量方程等等!

        考虑下面的示例,该示例解释了我们如何使用NumPy进行某些矩阵运算。

        import numpy as np
        A = np.array([[6, 1, 1],
                      [4, -2, 5],
                      [2, 8, 7]])
        print("A的秩:", np.linalg.matrix_rank(A))
        print("\n矩阵的迹:", np.trace(A))
        print("\nA的行列式:", np.linalg.det(A))
        print("\nA的逆矩阵:\n", np.linalg.inv(A))
        print("\nA的3次方:\n", np.linalg.matrix_power(A, 3))
        

        输出:

        A的秩: 3
        矩阵的迹: 11
        A的行列式: -306.0
        A的逆矩阵:
         [[ 0.17647059 -0.00326797 -0.02287582]
         [ 0.05882353 -0.13071895  0.08496732]
         [-0.11764706  0.1503268   0.05228758]]
        A的3次方:
         [[336 162 228]
         [406 162 469]
         [698 702 905]]

        让我们假设我们要解决这个线性方程组:

        x + 2*y = 8
        3*x + 4*y = 18

        可以使用linalg.solve方法解决此问题,如下例所示:

        import numpy as np
        # 系数
        a = np.array([[1, 2], [3, 4]])
        # 常数
        b = np.array([8, 18])
        print("线性方程的解:", np.linalg.solve(a, b))

        输出:

        线性方程的解: [ 2.  3.]

        最后,我们来看一个示例,该示例显示了如何使用最小二乘法进行线性回归。
        线性回归线的形式为w1 x + w 2 = y,并且它是使从每个数据点到该线的距离的平方和最小化的线。因此,给定n对数据(xi,yi),我们正在寻找的参数是w1和w2,它们将误差最小化:

        让我们看下面的例子:

        import numpy as np
        import matplotlib.pyplot as plt
        # x坐标
        x = np.arange(0, 9)
        A = np.array([x, np.ones(9)])
        # 线性产生的序列
        y = [19, 20, 20.5, 21.5, 22, 23, 23, 25.5, 24]
        # 获得回归线的参数
        w = np.linalg.lstsq(A.T, y)[0]
        # 画线
        line = w[0]*x + w[1] # regression line
        plt.plot(x, line, 'r-')
        plt.plot(x, y, 'o')
        plt.show()
        1. 输出:

        本NumPy教程的总结:
        NumPy是一个广泛使用的通用库,它是scipy,scikit-learn,tensorflow,matplotlib,opencv等许多其他计算库的核心。对NumPy的基本了解有助于有效地处理其他更高级别的库!