Python ndarray (n,) 与 (n,1) 在矩阵运算上的差别

165 阅读2分钟

以前一直以为 ndarray 的 (n,) 与 (n,1) 在运算上没有差别

其实如果你的运算一直是一维向量的运算的话,确实没有区别

但是如果你的运算涉及到了多维的矩阵,区别就在于 (n,) 不会被视为向量,而 (n,1) 会被视为向量

测试 1

(n,1) 之间的运算:

import numpy as np

N = 5
roots_num = 5

v = np.linspace(1, N, N).reshape((-1, 1))

root = np.linspace(1, roots_num, roots_num).reshape((-1, 1))

root * v.T

输出:

array([[ 1.,  2.,  3.,  4.,  5.],
       [ 2.,  4.,  6.,  8., 10.],
       [ 3.,  6.,  9., 12., 15.],
       [ 4.,  8., 12., 16., 20.],
       [ 5., 10., 15., 20., 25.]])

(n,) 之间的运算:

import numpy as np

N = 5
roots_num = 5

v = np.linspace(1, N, N)

root = np.linspace(1, roots_num, roots_num)

root * v.T

输出:

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

可以发现 (n,1) 之间的运算结果才是我们需要的矩阵,而对 (n,) 做转置,还是得到 (n,),所以运算结果是一个向量

测试 2

(n,1) 与 (n,m) 之间的运算

import numpy as np

N = 5
roots_num = 5

phi0 = np.linspace(1, roots_num * N, roots_num * N).reshape((roots_num, N))

root = np.linspace(1, roots_num, roots_num).reshape((-1, 1))

#%%
root * phi0

输出:

array([[  1.,   2.,   3.,   4.,   5.],
       [ 12.,  14.,  16.,  18.,  20.],
       [ 33.,  36.,  39.,  42.,  45.],
       [ 64.,  68.,  72.,  76.,  80.],
       [105., 110., 115., 120., 125.]])

(n,) 与 (n,m) 之间的运算

import numpy as np

N = 5
roots_num = 5

phi0 = np.linspace(1, roots_num * N, roots_num * N).reshape((roots_num, N))

root = np.linspace(1, roots_num, roots_num)

#%%
root * phi0

输出:

array([[  1.,   4.,   9.,  16.,  25.],
       [  6.,  14.,  24.,  36.,  50.],
       [ 11.,  24.,  39.,  56.,  75.],
       [ 16.,  34.,  54.,  76., 100.],
       [ 21.,  44.,  69.,  96., 125.]])

可见单纯一个 (n,) 与矩阵相乘,会把这个矩阵视为存着一个个 (n,) 数组,然后做数组相乘

而 (n,1) 与矩阵相乘,会遵循矩阵乘法,左矩阵的每行乘右矩阵的每列