NumPy 数学操作和广播

Jinku Hu 2023年1月30日 2018年7月14日
  1. NumPy 四则运算
  2. NumPy 广播
NumPy 数学操作和广播

我们会在接下来的几节中介绍 NumPy 的计算,包括简单的四则运算以及矩阵运算,首先我们从最常见的四则运算开始。

NumPy 四则运算

加减乘除四则运算,在 NumPy 中是最基本的运算,跟我们平常普通数字之间的运算,在表现形式上也很类似。

import numpy as np
arrayA = np.array([[1, 2, 3],[4, 5, 6],[7, 8, 9]])
arrayB = arrayA.T
#array([[1, 2, 3],
#       [4, 5, 6],
#       [7, 8, 9]])

arrayB = arrayA.T
#array([[1, 4, 7],
#       [2, 5, 8],
#       [3, 6, 9]])

arrayA + arrayB
#array([[ 2,  6, 10],
#       [ 6, 10, 14],
#       [10, 14, 18]])

arrayA - arrayB
#array([[ 0, -2, -4],
#       [ 2,  0, -2],
#       [ 4,  2,  0]])

arrayA * arrayB
#array([[ 1,  8, 21],
#       [ 8, 25, 48],
#       [21, 48, 81]])

arrayA / arrayB
#array([[1.        , 0.5       , 0.42857143],
#       [2.        , 1.        , 0.75      ],
#       [2.33333333, 1.33333333, 1.        ]])

这里需要注意的是矩阵乘法*运算,是将两个矩阵相同位置上的元素相乘得到结果矩阵上该位置上的元素,而不是矩阵运算上的内积,内积也就是点积,是通过 np.dot() 来计算的。

np.dot(arrayA, arrayB)
#array([[ 14,  32,  50],
#       [ 32,  77, 122],
#       [ 50, 122, 194]])

NumPy 广播

理论上,矩阵运算的两个矩阵需要具有相同的形状,也就是两矩阵的行列数相等。但在 NumPy 中,引入了广播(broadcasting)的概念,用于当两矩阵的形状不等时,假如有可能的话,会自动补齐数据,从而来实现运算。我们还是看下面的一个例子,

import numpy as np
arrayA = np.array([[1, 2, 3],[4, 5, 6],[7, 8, 9]])
arrayA + 1
#array([[ 2,  3,  4],
#       [ 5,  6,  7],
#       [ 8,  9, 10]])

这里 1 跟矩阵当中的所有元素相加,换句话说 1 从一个 (1, 1) 形状的矩阵,广播到了 (3, 3) 形状,数据用元素 1 填充。在实际 NumPy 中,arrayA + 1 时这样计算的

arrayA + np.array([[1,1,1],[1,1,1],[1,1,1]])

NumPy 广播还可以有下面的用法

两矩阵具有某一相同的维度,而另外一维其中一矩阵长度为 1

还是先来看具体例子,

arrayC = np.array([10, 11, 12])
arrayA + arrayC
#array([[11, 13, 15],
#       [14, 16, 18],
#       [17, 19, 21]])

矩阵 arrayA 的形状是 (3, 3),矩阵 arrayC 的形状是 (3, ),或者你可以把它看成是 (3, 1) 形状的,也就是它只有一行。它们满足有某一相同的维度(列数相同),另外一维其中某一矩阵长度为 1(矩阵 arrayC 的行数为 1),那么 NumPy 就会把 arrayC 上的唯一一行数据广播到三行,跟 arrayA 进行匹配。

同理,下面的例子是行数相同,而一矩阵的列数为 1 的情况。

arrayD = np.array([[10],[11],[12]])
#array([[10],
#       [11],
#       [12]])
arrayA + arrayD
#array([[11, 12, 13],
#       [15, 16, 17],
#       [19, 20, 21]])
Author: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn