在 python 中沿特定轴广播操作
Broadcast an operation along specific axis in python
在 python 中,假设我有一个方形 numpy
矩阵 X,大小为 n x n 并且我有一个大小为 n 的 numpy
向量 a。
非常简单,我想执行 X - a 的广播减法,但我希望能够指定沿着哪个维度,以便我可以指定减法沿轴 0 或轴 1。
如何指定轴?
让我们用随机元素生成数组
输入:
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
做减法,即我们要从X
的第一行、X
的第二行等减去a
。为了便于检查正确性,我们只使用 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
的第一个轴匹配。因为,X
是 2D
而 a
是 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
是不是在这里。
重要提示: 这里要注意的是 a
元素将沿着一个轴并且沿着该轴进行减法并且广播将沿着其他轴。因此,在这种情况下,即使沿 axis=1
发生减法,a
的元素也会沿 axis=0
.
传播
二.沿 axis=0
减法
类似地,让我们沿着 axis=0
进行减法,即我们要从 X
的第一列、X
的第二列等中减去 a
在。为了便于检查正确性,我们只使用 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
的第一个轴匹配。由于 X
是 2D
而 a
是 1D
,我们需要将 a
扩展到 2D
并保持所有元素沿其第一个轴a[:,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
早先得到的
从 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.]])
在 python 中,假设我有一个方形 numpy
矩阵 X,大小为 n x n 并且我有一个大小为 n 的 numpy
向量 a。
非常简单,我想执行 X - a 的广播减法,但我希望能够指定沿着哪个维度,以便我可以指定减法沿轴 0 或轴 1。
如何指定轴?
让我们用随机元素生成数组
输入:
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
做减法,即我们要从X
的第一行、X
的第二行等减去a
。为了便于检查正确性,我们只使用 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
的第一个轴匹配。因为,X
是 2D
而 a
是 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
是不是在这里。
重要提示: 这里要注意的是 a
元素将沿着一个轴并且沿着该轴进行减法并且广播将沿着其他轴。因此,在这种情况下,即使沿 axis=1
发生减法,a
的元素也会沿 axis=0
.
二.沿 axis=0
类似地,让我们沿着 axis=0
进行减法,即我们要从 X
的第一列、X
的第二列等中减去 a
在。为了便于检查正确性,我们只使用 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
的第一个轴匹配。由于 X
是 2D
而 a
是 1D
,我们需要将 a
扩展到 2D
并保持所有元素沿其第一个轴a[:,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
早先得到的
从 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.]])