NumPy 数组是具有相同类型和大小的项的 N 维容器。作为一种计算机编程数据结构,它受到资源和 dtype 的限制——有些值是 NumPy 数组无法表示的。由于这些限制,NumPy 数组并不完全等同于坐标向量的数学概念。然而,NumPy 数组通常用于(大约)表示向量。
数学还有一个向量空间的概念,其元素称为向量。矢量的一个示例是具有方向和大小的对象。坐标向量只是向量相对于特定坐标系的表示。因此,虽然 NumPy 数组最多可以记录向量的坐标(默认情况下,相对于坐标系),但它不能捕获向量的完整抽象概念。向量的抽象概念在没有提及坐标系的情况下存在。
此外,向量空间可以是坐标以外的事物的集合。例如,函数族可以形成向量空间。这些函数将是向量。所以这是另一个例子,其中 NumPy 数组根本不等同于向量。
线性代数区分“行向量”和“列向量”。NumPy 中没有这样的区别。只有n维数组。请记住,NumPy 是围绕将类似数组的容器推广到大于 2的N维度的愿望而构建的。因此,NumPy 操作的定义方式可以推广到更高的维度。N
例如,转置一个 NumPy 形状数组会(a,b,c,d)返回一个形状数组(d,c,b,a)——轴是颠倒的。在二维中,这意味着一个形状数组(a,b)(即a行、b列)变成了一个形状数组(b,a)(即b行、a列)。所以 NumPy 的转置概念与二维数组的线性代数概念很好地匹配。
但这也意味着 shape 的一维 NumPy 数组的转置
(a,)仍然具有 shape (a,)。没有什么变化。它仍然是相同的一维数组。因此,“行向量”和“列向量”之间没有真正的区别。
NumPy 使用二维数组模仿行向量和列向量的概念。一个形状数组(5,1)有 5 行 1 列。您可以将其视为列向量,在线性代数中需要列向量的任何地方,都可以使用 shape 数组(n,1)。同样,在线性代数中,无论您在哪里看到行向量,都可以使用 shape 数组(1,n)。
然而,NumPy 也有广播的概念,广播的规则之一是当操作需要时,额外的轴将自动添加到其形状左侧的任何数组中。因此,一个 1 维 NumPy 形状数组(5,)可以广播到一个 2 维形状数组(1,5)(或 3 维形状数组(1,1,5)等)。
这意味着一维形状数组可以被认为是一个行向量,因为它会在必要时(5,)自动广播到一个形状数组。(1,5)
另一方面,广播永远不会在形状的右侧添加额外的轴。您必须明确地这样做。因此,如果theta是一个 shape 数组(5,),要创建 shape 的“列向量”,(5,1)您必须使用或 简写自己显式添加新轴。theta[:, np.newaxis]theta[:, None]
什么是正确的numpy等价物θTX?
如果,例如,
In [4]: import numpy as np
In [5]: theta = np.array([1,2,3,4,5])[:, np.newaxis]
In [7]: X = np.random.randint(10, size=(5,3))
In [8]: X
Out[8]:
array([[4, 0, 3],
[6, 9, 1],
[7, 8, 7],
[4, 2, 6],
[7, 7, 2]])
那么你可以计算θTX使用
In [18]: np.dot(theta.T, X)
Out[18]: array([[88, 85, 60]])
请注意,np.dot定义为
a对于 N 维,它是最后一个轴和倒数第二个轴的和积b
dot(a, b)[i,j,k,m] = sum(a[i,j,:] * b[k,:,m])
这具有以下属性
对于二维数组,它相当于矩阵乘法,对于一维数组,它相当于向量的内积(没有复共轭)。
请注意,NumPy 也有一个matrix子类,ndarray其乘法运算符被定义为匹配二维矩阵乘法。因此,如果theta并且X是 NumPy 矩阵,那么您可以编写theta.T * X而不是np.dot(theta.T, X). 这可以使将数学转换为 NumPy 代码更具可读性。
或者,如果您有 Python3.5 或更高版本,您可以使用常规 NumPy 数组并编写theta.T @ X.