繁体   English   中英

Numpy 矩阵减法在另一个矩阵的每一列

[英]Numpy matrix subtraction over each column of another matrix

我知道在 numpy 中,如果你有一个矩阵A并且我通过执行A - v减去一个向量vv将被广播,以便v成为与A相同的维度,并且将执行元素减法。

我想知道是否必须使用相同的 A但使用不同的v多次执行上述操作,是否可以使用矢量化来完成。

一个天真的实现如下

def foo(A, V):
   """
   @params: A, V
   A - an n by m matrix
   V - a list of n by 1 column vectors
   @returns: result
   """

   result = []
   for v in V:
      result.append(A-v)
   return result

我知道我可以将V作为 by p 矩阵传递,其中每列代表一个v 但是,我想不出用线性代数来描述上述操作的任何方式

例如,如果

 A = [[1 2 3], 
      [1 2 3]]

 V = [[1 4], 
      [1 4]]  

output 应该是两个矩阵

[
  [[0 1 2], 
  [0,1,2]], 

  [[-3 -2 -1], 
  [-3 -2, -1]]
]
a = np.zeros((4,3)) + [1,2,3]
V = [np.ones(3),np.ones(3)*2,np.ones(3)*3]

你想要的是

>>> a-V[0]
array([[0., 1., 2.],
       [0., 1., 2.],
       [0., 1., 2.],
       [0., 1., 2.]])
>>> a-V[1] 
array([[-1.,  0.,  1.],
       [-1.,  0.,  1.],
       [-1.,  0.,  1.],
       [-1.,  0.,  1.]])
>>> a-V[2]
array([[-2., -1.,  0.],
       [-2., -1.,  0.],
       [-2., -1.,  0.],
       [-2., -1.,  0.]])

将向量堆叠在 V 中,然后添加要减去的维度。

>>> W = np.vstack(V)
>>> a - W[:,None,:]
array([[[ 0.,  1.,  2.],
        [ 0.,  1.,  2.],
        [ 0.,  1.,  2.],
        [ 0.,  1.,  2.]],

       [[-1.,  0.,  1.],
        [-1.,  0.,  1.],
        [-1.,  0.,  1.],
        [-1.,  0.,  1.]],

       [[-2., -1.,  0.],
        [-2., -1.,  0.],
        [-2., -1.,  0.],
        [-2., -1.,  0.]]])

再次尝试调整(n,m)(4,3)

a = np.zeros((4,3)) + [1,2,3]       # (n.m) = (4,3)
V = [np.ones(4),np.ones(4)*2,np.ones(4)*3]  # three (nx1) vectors
W = np.vstack(V)

>>> a.shape
(4, 3)
>>> W.shape
(3, 4)
>>> Z = a - W[...,None] 
>>> Z[0]
array([[0., 1., 2.],
       [0., 1., 2.],
       [0., 1., 2.],
       [0., 1., 2.]])
>>> Z[1]
array([[-1.,  0.,  1.],
       [-1.,  0.,  1.],
       [-1.,  0.,  1.],
       [-1.,  0.,  1.]])
>>> Z[2]
array([[-2., -1.,  0.],
       [-2., -1.,  0.],
       [-2., -1.,  0.],
       [-2., -1.,  0.]])
>>> Z.shape             
(3, 4, 3)
In [104]:  A = [[1, 2, 3],
     ...:       [1, 2, 3]]
     ...: 
     ...:  V = [[1, 4],
     ...:       [1, 4]]
In [105]: A=np.array(A);V=np.array(V)
In [106]: A              # (n,m)
Out[106]: 
array([[1, 2, 3],
       [1, 2, 3]])
In [107]: V               # (n,p)
Out[107]: 
array([[1, 4],
       [1, 4]])

迭代减法; [0]用于制作数组 (2,1) (与 (2,3) A一起广播:

In [108]: [A-V[:,[0]], A-V[:,[1]]]
Out[108]: 
[array([[0, 1, 2],
        [0, 1, 2]]),
 array([[-3, -2, -1],
        [-3, -2, -1]])]

让我们尝试整个数组广播:

In [109]: A[None,:,:]-V[:,:,None]
Out[109]: 
array([[[ 0,  1,  2],
        [-3, -2, -1]],

       [[ 0,  1,  2],
        [-3, -2, -1]]])

糟糕,混合错误; 再试一次,将V更改为 (p,n)。 如果V不是 (2,2),那就更清楚了:

In [110]: A[None,:,:]-V.T[:,:,None]
Out[110]: 
array([[[ 0,  1,  2],
        [ 0,  1,  2]],

       [[-3, -2, -1],
        [-3, -2, -1]]])

使用 (2,4) V

In [112]: V1=np.hstack((V,V))
In [113]: V1.shape
Out[113]: (2, 4)
In [114]: (A[None,:,:]-V1.T[:,:,None]).shape
Out[114]: (4, 2, 3)
In [115]: (A-V1.T[:,:,None]).shape
Out[115]: (4, 2, 3)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM