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. 延伸阅读
- Numpy 中如何对矩阵的特征对排序
- Python 中怎样合并数据
6.2. 参考文献
- [1]M. Wes, Python for Data Analysis, 2nd. Beijing: O’Reilly, 2017.
- [1]J. VanderPlas, Python Data Science Handbook. Beijing: O’Reilly, 2016.