在numpy中计算两个一维向量的点积

14
我在Python中使用numpy计算向量乘积。我有一个n x 1的向量x,想要计算x*x_transpose。这会导致问题,因为x.T或x.transpose()不能影响一个一维向量(numpy以相同方式表示垂直和水平向量)。但是,如何在numpy中计算(n x 1) x (1 x n)的向量乘积呢?使用numpy.dot(x,x.T)得到的是一个标量,而不是我想要的二维矩阵。

@ᴋᴇʏsᴇʀ 它确实会给出一个矩阵。 - Chris Hagmann
@cdhagmann 是的。我注意到了这些维度。 - keyser
2
一个(1xN)矩阵与一个(Nx1)矩阵相乘应该得到一个标量。但是一个(Nx1)矩阵与一个(1xN)矩阵的乘积则不应该。 - Vjeetje
你的数组不是1xN或Nx1,而是一维的。如果你想要2维数组,请使用2维数组。 - pv.
5个回答

16

你实际上是在计算一个外积

你可以使用np.outer

In [15]: a=[1,2,3]

In [16]: np.outer(a,a)
Out[16]:
array([[1, 2, 3],
       [2, 4, 6],
       [3, 6, 9]])

3
10分钟时间结束后我会接受这个。 - Vjeetje

6

虽然 np.outer 是实现此操作的最简单方法,但我想提一下如何操作 (N,) 形状的数组来完成此操作:

In [17]: a = np.arange(4)
In [18]: np.dot(a[:,None], a[None,:])
Out[18]:
array([[0, 0, 0, 0],
       [0, 1, 2, 3],
       [0, 2, 4, 6],
       [0, 3, 6, 9]])

In [19]: np.outer(a,a)
Out[19]:
array([[0, 0, 0, 0],
       [0, 1, 2, 3],
       [0, 2, 4, 6],
       [0, 3, 6, 9]])

你可以将 None 替换为 np.newaxis

另一种更为奇特的方法是使用 np.einsum:

In [20]: np.einsum('i,j', a, a)
Out[20]:
array([[0, 0, 0, 0],
       [0, 1, 2, 3],
       [0, 2, 4, 6],
       [0, 3, 6, 9]])

为了好玩,这里提供一些时间数据,但是由于硬件和numpy版本/编译的不同,这些数据可能会有所不同:

较小的向量

In [36]: a = np.arange(5, dtype=np.float64)

In [37]: %timeit np.outer(a,a)
100000 loops, best of 3: 17.7 µs per loop

In [38]: %timeit np.dot(a[:,None],a[None,:])
100000 loops, best of 3: 11 µs per loop

In [39]: %timeit np.einsum('i,j', a, a)
1 loops, best of 3: 11.9 µs per loop

In [40]: %timeit a[:, None] * a
100000 loops, best of 3: 9.68 µs per loop

还有一些更大的东西

In [42]: a = np.arange(500, dtype=np.float64)

In [43]: %timeit np.outer(a,a)
1000 loops, best of 3: 605 µs per loop

In [44]: %timeit np.dot(a[:,None],a[None,:])
1000 loops, best of 3: 1.29 ms per loop

In [45]: %timeit np.einsum('i,j', a, a)
1000 loops, best of 3: 359 µs per loop

In [46]: %timeit a[:, None] * a
1000 loops, best of 3: 597 µs per loop

3
不要忘记 a[:,None] * a - Daniel

1

另一种选择是使用二维数组定义行/列向量,例如:

a = np.array([1, 2, 3], ndmin=2)
np.dot(a.T, a)

array([[1, 2, 3],
   [2, 4, 6],
   [3, 6, 9]])

1
如果您想要内积,请使用 numpy.dot(x,x),如果想要外积,请使用 numpy.outer(x,x)

0
另一种选择是使用numpy.matrix
>>> a = np.matrix([1,2,3])
>>> a
matrix([[1, 2, 3]])
>>> a.T * a
matrix([[1, 2, 3],
        [2, 4, 6],
        [3, 6, 9]])

通常情况下,我们更倾向于使用numpy.arrays。但是,在处理较长的表达式时,使用numpy.matrices会更易读。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接