前言
今天学习 python 里的 numpy 库里的 dot 方法,花了点功夫。
正文
这是我练习的代码:
import numpy as np x = np.array([ [1, 2], [3, 4] ]) y = np.array([ [5, 6], [7, 8] ]) v = np.array([9, 10]) w = np.array([11, 12]) print(np.dot(v, w)) print(v.dot(w)) print(np.dot(x, y)) print(x.dot(y))
这是执行结果:
219 219 [[19 22] [43 50]] [[19 22] [43 50]]
让我郁闷的地方:x、y 是两个二维数组,v、w 是两个一维数组。np.dot(v, w) 和 v.dot(w) 是同一个效果,都表示 v 点乘 w。
- 219 怎么来的?
心中暗暗思忖:219 = 9 x 11 + 10 x 12。 - [[19, 22], [43, 50]] 怎么来的?
顺着上个问题,心中继续暗暗思忖:不就是对应元素相乘嘛,那么 [[19, 22], [43, 50]] = [[1 x 5, 2 x 6], [3 x 7, 4 x 8]]。核对的时候,发现并不是这么玩的,这个公式根本不对。
我找了下 numpy 的官方文档,是这么介绍的,
If both a and b are 1-D arrays, it is inner product of vectors (without complex conjugation).
If both a and b are 2-D arrays, it is matrix multiplication, but using matmul or a @ b is preferred.
If either a or b is 0-D (scalar), it is equivalent to multiply and using numpy.multiply(a, b) or a * b is preferred.
If a is an N-D array and b is a 1-D array, it is a sum product over the last axis of a and b.
If a is an N-D array and b is an M-D array (where M>=2), it is a sum product over the last axis of a and the second-to-last axis of b。
代码测试前 4 条(第 5 条就不测了),
import numpy as np print(np.dot(np.array([1, 2]), np.array([3, 4]))) print(np.dot(np.array([[1, 2, 3],[4, 5, 6]]), np.array([[7, 8], [9, 10], [11, 12]]))) print(np.dot(np.array(3), np.array(4))) print(np.dot(np.array([[1, 2],[3, 4]]), np.array([5, 6])))
测试结果,
11 [[ 58 64] [139 154]] 12 [17 39]
1.可以看到两个一维数组点乘的结果是一个标量,11 = 1 x 3 + 2 x4。
2.可以看到两个二维数组点乘的结果是 [[58, 64], [139, 154]] = [[1 x 7 + 2 x 9 + 3 x 11, 1 x 8 + 2 x 10 + 3 x 12],[4 x 7 + 5 x 9 + 6 x 11, 4 x 8 + 5 x 10 + 6 x 12]],即 m x s 的数组点乘 s x n 的数组,结果是 m x n 的数组,千万别想我最开始那么犯错。
3.可以看到两个标量点乘的结果是一个标量,12 = 3 x 4。
4.可以看到二维数组点乘一维数组的结果是 [17, 39] = [1 x5 + 2 x 6, 3 x 5 + 4 x 6]。
以上可以看出来,第 4 条和第 2 条很像,其实第 4 条就是 result = A(2-Dimension) x B(1-Dimension)的转置。第 1 条和第 2 条也很像,其实就是 result = A(1-Dimension) x B(1-Dimension)的转置,再把结果里的元素相加了。
终于结束了,可以亮出来大学的《线性代数》了,也蛮不容易的,大学时候线代挂科还补考了。
《线性代数》同济第五版
矩阵运算