0 一维 array 对象
np中的一维向量有个特殊的用法,即将行或列设为 None,来进行转换。
a = np.array(range(5)) # np.arange(5)
a.shape
Out: (5,) # 实际是行向量,注意表示方式的不同。
a[None,:].shape
Out: (1,5) # 1 x 5 行向量
a[:,None].shape
Out: (5,1) # 5 x 1 列向量
进一步理解上述操作。
a = a[None,:]
a.shape
out: (1,5)
a = a[None,:]
a.shape
out: (1,1,5)
0-1 理解 Numpy 中的 Shape
The meaning of shapes in Numpy
The best way to think about NumPy arrays is that they consist of two parts, a data buffer which is just a block of raw elements, and a view which describes how to interpret the data buffer.
理解 Numpy 中的 shape 的方法:
Numpy 中用两部分来表示数组形状:数据本身和形状描述。
具体解释可以看原文。
0-2 Numpy 中的 (R,)
是自由变量吧?即可以是行向量,也可以是列向量。证据:转置。
a = np.array(range(3)) # np.arange(3)
a is a.T
out: False
b = a.T
a[0] = 1
b
out: [1,1,2]
a.shape
out: (3,)
a.T.shape
out: (3,)
但实际上,Numpy 把 (R,) 当做行向量来理解。 将一个 (5,) 向量和一个 (3,5) 的二维矩阵相乘会出错(对也不对,没有深入理解。见下一小节的解释。):
a = np.arange(5)
b = np.reshape(np.arange(15),(3,5))
np.dot(a,b)
ValueError: shapes (5,) and (3,5) not aligned: 5 (dim 0) != 3 (dim 0)
0-3 纠错和补充
numpy 中的 broadcasting(广播)机制 一文中讲解了 广播 的机制,并解释了一维数组的行为。
一维数组置于矩阵乘法的左部,被视为一个行向量;
一维数组置于矩阵乘法的右部,被视为一个列向量;
矩阵乘法运算结束得到的向量仍是一维数组。
试验了下,确实如此:
a = np.arange(5)
b = np.reshape(np.arange(15),(3,5))
np.dot(b,a).shape
out: (3,)
1 向量的表示方法
(5,) 表示的是一个 1 x 5 的 行 向量。
a = np.array(range(5)) # np.arange(5)
Out[1]: array([0, 1, 2, 3, 4])
a.shape
Out[2]: (5,)
2 向量和矩阵的乘积
(5,) 和 (5,3) 的矩阵是可以直接用 np.dot() 相乘的(矢量乘法),得到一个 1 x 3 的向量。
b = np.reshape(np.array(range(15)),(5,3))
Out[3]:
array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11],
[12, 13, 14]])
np.dot(a,b)
Out[4]: array([ 90, 100, 110])
但不能直接相乘,会提示维度不对应,无法进行广播。此时,python 是将 a 当做行向量的。
a * b
ValueError: operands could not be broadcast together with shapes (5,) (5,3)
a * b.T
out: array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
也可以强行将 a 转换为一个 1 x 5 的行向量,再进行乘法。
a = a[None,:] # 1:5 行向量
np.dot(a,b)
Out[4]: array([ 90, 100, 110])
3 向量和向量的乘法
3-1 对应元素相乘
c = a
a * c
Out[5]: array([ 0, 1, 4, 9, 16])
3-2 点乘
np.dot(a,c)
Out[6]: 30
3-3 叉乘
a(5,) 和 c(5,) 的叉乘需要将第二个变为列向量,c[:,None]。
a * c[:,None] # np.outer(a,c)
Out[7]: array([[ 0, 0, 0, 0, 0],
[ 0, 1, 2, 3, 4],
[ 0, 2, 4, 6, 8],
[ 0, 3, 6, 9, 12],
[ 0, 4, 8, 12, 16]])