python range数组乘以一个数 numpy数组乘一个数_NumPy


python range数组乘以一个数 numpy数组乘一个数_NumPy_02


1. 问题

ndarray 是 NumPy 的基础元素,NumPy 又主要是用来进行矩阵运算的。那么具体来说,ndarray 是如何进行普通矩阵运算的呢?

2. 分析

首先,在矩阵用 +-*/ 这些常规操作符操作的时候,是对元素进行操作。这和其他诸如 MATLAB 等语言不一样。

比如


ar = np.array([[20, 21, 22],
       [23, 24, 25]])
ar * ar


结果输出


array([[400, 441, 484],
       [529, 576, 625]])


可见, * 并没有进行矩阵乘法,而是矩阵和矩阵的元素进行了相乘。想要进行矩阵乘法计算,需要用dot方法


ar3 = np.array([[1, 2, 3],
       [4, 5, 6],
       [3, 2, 1]])
ar3.dot(ar3)


结果输出


array([[18, 18, 18],
       [42, 45, 48],
       [14, 18, 22]])
ar3 * ar3


结果输出


array([[ 1,  4,  9],
       [16, 25, 36],
       [ 9,  4,  1]])


那不同维数的矩阵如何处理?比如一个二维矩阵和一维向量,如何操作?这就需要用到 NumPy 的 Broadcasting 功能。Broadcasting 可以把低维矩阵扩展成高维矩阵进行运算。比如最简单的矩阵和数字相加,其实就等于把数字扩展成了一个和矩阵等大的新矩阵,然后对应元素相加。

Broadcasting 规则很简单

Array Broadcasting in Numpy — NumPy v1.19.dev0 Manual

即,Broadcasting 的时候,需要两个矩阵的尾轴大小相等,或者其中一个是 1。

这么说有点枯燥,举例如下


ar = np.array([[20, 21, 22],
       [23, 24, 25]])
t = array([1, 2, 3])
h = array([1, 2])

ar / t


结果输出


array([[30.        , 15.5       , 10.66666667],
       [33.        , 17.        , 11.66666667]])

ar / h
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-21-711a92d431f2> in <module>
----> 1 ar / h

ValueError: operands could not be broadcast together with shapes (2,3) (2,)


t 和 h 都是只有一个维度,所以其大小就等于尾维。t 的尾轴大小为3,ar 是 2x3,尾轴也是3,两者相等,可以计算。h 的尾轴大小为2,两者不等,所以出现错误。

其 Broadcasting 可以理解为


axis 1 fix
                         +------------>
ar [20, 21, 22]   /      | t [1, 2, 3]
   [23, 24, 25]     axis |   [1, 2, 3]
                    0    |
                         v broadcast by axis 0


可见,把 t 扩展成和 ar 一样大小后,两者在元素级别上对应相除,即可得到之前的结果。

3. 扩展

刚才提到了 NumPy 的轴,可以进一步扩展一下。轴在 NumPy里面通常用参数axis传递,比如 axis=0

NumPy 的坐标轴可以用下图来表示


axis 1
        +--------------->
        |       0     1     2
        |     +----+-----+----+
axis 0  |  0  |0,0 | 0,1 | 0,2|
        |     +---------------+
        |  1  |1,0 | 1,1 | 1,2|
        |     +---------------+
        v  2  |2,0 | 2,1 | 2,2|
              +----+-----+----+


当我们指定某一参数的时候,就可以理解成沿着这个方向执行操作。比如


Input: ar = np.arange(6).reshape(2,3)
Output:    array([[0, 1, 2],
                  [3, 4, 5]])

Input: np.sum(ar, axis=0)
Output:    array([3, 5, 7])

Input: np.sum(ar, axis=1)
Output:    array([ 3, 12])


可见,当指定 axis=0 时,求和会沿着0轴方向进行,最后形成一个三个数字的向量;当指定 axis=1 时,求和会沿着1轴方向进行,最后形成一个两个数字的向量。

4. 总结

今天我们大致总结了 NumPy 的运算规则及坐标轴的含义。NumPy 作为基本库,是诸如 pandas、scikit-learn 等库的基础,掌握 NumPy 的相关规则,应是基本功。

相关代码均已上传到 Data2Science@Github

6. 扩展

6.1. 延伸阅读

  1. Numpy 中如何对矩阵的特征对排序
  2. Python 中怎样合并数据

6.2. 参考文献

  1. [1]M. Wes, Python for Data Analysis, 2nd. Beijing: O’Reilly, 2017.
  2. [1]J. VanderPlas, Python Data Science Handbook. Beijing: O’Reilly, 2016.