14

在 python 中,假设我有一个大小为nxnnumpy的方阵X,并且我有一个大小为n的向量anumpy

很简单,我想执行X - a的广播减法,但我希望能够指定沿哪个维度,以便我可以指定减法是沿轴 0 还是轴 1。

如何指定轴?

4

2 回答 2

14

让我们用随机元素生成数组

输入:

In [62]: X
Out[62]: 
array([[ 0.32322974,  0.50491961,  0.40854442,  0.36908488],
       [ 0.58840196,  0.1696713 ,  0.75428203,  0.01445901],
       [ 0.27728281,  0.33722084,  0.64187916,  0.51361972],
       [ 0.39151808,  0.6883594 ,  0.93848072,  0.48946276]])

In [63]: a
Out[63]: array([ 0.01278876,  0.01854458,  0.16953393,  0.37159562])

一、减法沿axis=1

让我们一起做减法axis=1,即我们a要从 的第一行X、第二行等中减去X。为了便于检查正确性,我们只使用第一行X

In [64]: X[0] - a
Out[64]: array([ 0.31044099,  0.48637503,  0.23901049, -0.00251074])

深入那里,那里发生的事情是:

X[0,0] - a[0], X[0,1] - a[1], X[0,2] - a[2] , X[0,3] - a[3]

因此,我们将 的第二个轴X与 的第一个轴匹配a。因为,Xis2Dais 1D,两者都已经对齐:

X :  n x n
a :      n

所以,我们只需要做X-a所有的减法:

In [65]: X-a
Out[65]: 
array([[ 0.31044099,  0.48637503,  0.23901049, -0.00251074],
       [ 0.5756132 ,  0.15112672,  0.5847481 , -0.3571366 ],
       [ 0.26449405,  0.31867625,  0.47234523,  0.1420241 ],
       [ 0.37872932,  0.66981482,  0.76894679,  0.11786714]])

并且,最后看看我们是否已经X[0] - a获得了较早的是这里。

重要提示: 这里要注意的是,aelems 将沿着一个轴,并且沿着那个减法进行,并且广播将沿着另一个轴发生。因此,在这种情况下,即使减法发生沿axis=1a也会沿 广播axis=0

二、减法沿axis=0

类似地,让我们做减法axis=0,即我们a要从 的第一个列X,第二个列中减去X,依此类推。为了便于检查正确性,我们只使用 的第一列X

In [67]: X[:,0]-a
Out[67]: array([ 0.31044099,  0.56985738,  0.10774888,  0.01992247])

深入那里,那里发生的事情是:

X[0,0] - a[0], X[1,0] - a[1], X[2,0] - a[2] , X[3,0] - a[3]

因此,我们将 的第一个轴X与 的第一个轴匹配a。因为, Xis2Dais 1D, 我们需要沿着它的第一个轴延伸并保持所有a元素:2Da[:,None]

X          :  n x n
a[:,None]  :  n x 1

所以,我们要做X-a[:,None]所有的减法:

In [68]: X-a[:,None]
Out[68]: 
array([[ 0.31044099,  0.49213085,  0.39575566,  0.35629612],
       [ 0.56985738,  0.15112672,  0.73573745, -0.00408557],
       [ 0.10774888,  0.16768691,  0.47234523,  0.34408579],
       [ 0.01992247,  0.31676379,  0.5668851 ,  0.11786714]])

并且,最后看看我们是否已经X[:,0] - a获得了较早的是这里。

于 2016-09-07T05:18:55.567 回答
9

从 2 个不同的维度开始(至少在标签中)

  • X形状(n,m)
  • a形状(n,)
  • b形状(m,)

结合这些的方法是:

(n,m)-(n,) => (n,m)-(n,1) => (n,m)
X - a[:,None]     

(n,m)-(m,) => (n,m)-(1,m) => (n,m)
X - b[None,:]
X - b      # [None,:] is automatic, if needed.

基本点是,当数量维度不同时,numpy可以在开始时添加新维度,但您必须明确在末尾添加新维度。

或者将 2 个 1d 数组组合在一个外部产品中(差异):

(n,) - (m,) => (n,1)-(1,m) => (n,m)
a[:,None] - b[None,:]
a[:,None] - b

如果没有这些规则,a-b可能会导致(n,m)(m,n)或其他东西。

并有 2 个匹配的长度数组:

(n,) - (n,) => (n,)
a - a

或者

(n,) - (n,) => (n,1)-(1,n) => (n,n)
a[:,None]-a[None,:]

==============

要编写一个带axis参数的函数,您可以使用np.expand_dims

In [220]: np.expand_dims([1,2,3],0)
Out[220]: array([[1, 2, 3]])    # like [None,:]
In [221]: np.expand_dims([1,2,3],1)
Out[221]:             # like [:,None]
array([[1],
       [2],
       [3]])

def foo(X, a, axis=0):
    return X - np.expand_dims(a, axis=axis)

用作:

In [223]: foo(np.eye(3),[1,2,3],axis=0)
Out[223]: 
array([[ 0., -2., -3.],
       [-1., -1., -3.],
       [-1., -2., -2.]])
In [224]: foo(np.eye(3),[1,2,3],axis=1)
Out[224]: 
array([[ 0., -1., -1.],
       [-2., -1., -2.],
       [-3., -3., -2.]])
于 2016-09-07T07:09:17.473 回答