代码之家  ›  专栏  ›  技术社区  ›  coolscitist

从没有循环的矩阵B的每一行中减去矩阵A的每一行

  •  6
  • coolscitist  · 技术社区  · 7 年前

    给定两个数组, A (形状:M X C)和 B (形状:N X C),有没有办法减去 A. 从每行 B 不使用循环?最终输出为形状(M N X C)。


    实例

    A = np.array([[  1,   2,   3], 
                  [100, 200, 300]])
    
    B = np.array([[  10,   20,   30],
                  [1000, 2000, 3000],
                  [ -10,  -20,   -2]])
    

    所需结果(可以有其他形状)(编辑):

    array([[  -9,   -18,   -27],
           [-999, -1998, -2997],
           [  11,    22,     5],
           [  90,   180,   270],
           [-900, -1800, -2700],
           [ 110,   220,   302]])
    
    Shape: 6 X 3
    

    (循环太慢,“outer”会减去每个元素,而不是每行)

    2 回复  |  直到 4 年前
        1
  •  9
  •   kmario23 Mazdak    4 年前

    通过利用 broadcasting 例如:

    In [28]: (A[:, np.newaxis] - B).reshape(-1, A.shape[1])
    Out[28]: 
    array([[   -9,   -18,   -27],
           [ -999, -1998, -2997],
           [   11,    22,     5],
           [   90,   180,   270],
           [ -900, -1800, -2700],
           [  110,   220,   302]])
    

    或者,比 广播 ,我们必须使用 numexpr 例如:

    In [31]: A_3D = A[:, np.newaxis]
    In [32]: import numexpr as ne
    
    # pass the expression for subtraction as a string to `evaluate` function
    In [33]: ne.evaluate('A_3D - B').reshape(-1, A.shape[1])
    Out[33]: 
    array([[   -9,   -18,   -27],
           [ -999, -1998, -2997],
           [   11,    22,     5],
           [   90,   180,   270],
           [ -900, -1800, -2700],
           [  110,   220,   302]], dtype=int64)
    

    另一种效率最低的方法是使用 np.repeat np.tile 匹配两个阵列的形状。但是,请注意,这是 效率最低 选项,因为它使 副本 尝试匹配形状时。

    In [27]: np.repeat(A, B.shape[0], 0) - np.tile(B, (A.shape[0], 1))
    Out[27]: 
    array([[   -9,   -18,   -27],
           [ -999, -1998, -2997],
           [   11,    22,     5],
           [   90,   180,   270],
           [ -900, -1800, -2700],
           [  110,   220,   302]])
    
        2
  •  1
  •   Rodrigo de Azevedo    7 年前

    使用 Kronecker product ( numpy.kron ):

    >>> import numpy as np
    >>> A = np.array([[  1,   2,   3], 
    ...               [100, 200, 300]])
    >>> B = np.array([[  10,   20,   30],
    ...               [1000, 2000, 3000],
    ...               [ -10,  -20,   -2]])
    >>> (m,c) = A.shape
    >>> (n,c) = B.shape
    >>> np.kron(A,np.ones((n,1))) - np.kron(np.ones((m,1)),B)
    array([[   -9.,   -18.,   -27.],
           [ -999., -1998., -2997.],
           [   11.,    22.,     5.],
           [   90.,   180.,   270.],
           [ -900., -1800., -2700.],
           [  110.,   220.,   302.]])