使用 'None' 进行成对操作的 numpy 索引
numpy indexing using 'None' for pairwise operations
如果我有两个像这样的 numpy 数组
a = np.array([1, 2])
b = np.array([3, 4])
我想添加所有成对组合,我可以轻松做到
c = a + b[:, None]
c
array([[4, 5],
[5, 6]])
得到1+3、2+3和1+4[=28=的结果], 2+4。
为什么这样做? 'None' 在做什么?我可以打印出来
b[:, None]
[[3]
[4]]
但我不确定为什么这会告诉 numpy 进行成对组合。我也很好奇,与 itertools.combinations.
相比,它是否在幕后有效实施
您正在做的是添加一个新轴:"column" 轴。 b
以前没有,所以现在它是一个列向量,将按列添加;它基本上就像在列中重复,并且 a
在行中重复一样:
a+b[:, None] = [1,2] + [[3], = [[1,2], + [[3],[3],
[4]] [1,2]] [4],[4]]
这里是 how/why:
首先要做的事情是:numpy
默认情况下进行元素加法和乘法。这意味着如果 a=np.array([1,2])
那么 a+2=np.array([1+2,2+2])=np.array([3,5])
.
import numpy as np
A = np.array([[1, 2],
[3, 4]])
B = np.array([[1,1],
[0,0]])
这里 A+B
是元素明智的,我们会得到
A+B = [[1+1,2+1], = [[2,3],
[3+0,4+0]] = [3,4]]
如果我们转置矩阵 B
(使用 B.T
)
现在 B.T
将具有值
B.T= np.array([[1,0],
[1,0]])
如果我们这次按元素来做,我们会得到:
A+B.T=[[1, 2] + [[1,0] = [[2,2],
[3, 4]] [1,0]] [4,4]]
另外要注意的是(B
不是转置)
a = np.array([1,2])
B+a = [[1,2], + [[2, 3],
[1,2]] [1, 2]]
它也是按元素排列的,但是在两行上!也就是说 a
实际上是 "repeated" 有两行,并且按元素添加到 B
.
此外,Numpy docs表示None
,在切片中,是另一种写法np.newaxis
。在您的情况下,切片中的 None
选项基本上是在添加之前转置 b
-向量!
可以获得完全相同的结果
import numpy as np
a = np.array([1, 2])
b = np.array([3, 4])
c=a+b.reshape(2,1)
d=a+b.reshape(-1,1)
e=a+b[:, np.newaxis]
此处c
、d
和e
的值相同!
要回答您问题的第一部分,b[:, None]
是一种特殊类型的切片,其行为与 b[:, np.newaxis]
相同,因为它将长度为 1 的轴添加到您的数组中。
>>> b.shape
(2,)
>>> b[:, None].shape
(2, 1)
此行为记录在 numpy
docs [1] 中,强调我的:
The newaxis
object can be used in all slicing operations to create an axis of length one. newaxis
is an alias for None
, and None
can be used in place of this with the same result.
所以现在我们有两个数组:
array([1, 2]) + array([[3],
[4]])
将这两个数组相加得到:
array([[4, 5],
[5, 6]])
这背后的 "magic" numpy
broadcasting[2]. This article [3] 是开始理解该主题的极好资源。
文章的主要内容如下:
numpy
操作通常逐个元素地完成,这需要两个数组具有完全相同的形状。但是,如果两个数组具有相同的尾轴 或者其中一个尾轴等于一个 (这是在你的案例中表现出的行为)。
在您的例子中,发生了广播,因此该操作等效于对以下 2x2 数组求和:
array([[1, 2], + array([[3, 3],
[1, 2]]) [4, 4]])
由于 numpy 操作是逐个元素完成的,因此将产生所需的输出:
array([[4, 5],
[5, 6]])
[1]https://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#numpy.newaxis
[2]https://docs.scipy.org/doc/numpy-1.13.0/user/basics.broadcasting.html
[3]http://scipy.github.io/old-wiki/pages/EricsBroadcastingDoc
如果我有两个像这样的 numpy 数组
a = np.array([1, 2])
b = np.array([3, 4])
我想添加所有成对组合,我可以轻松做到
c = a + b[:, None]
c
array([[4, 5],
[5, 6]])
得到1+3、2+3和1+4[=28=的结果], 2+4。
为什么这样做? 'None' 在做什么?我可以打印出来
b[:, None]
[[3]
[4]]
但我不确定为什么这会告诉 numpy 进行成对组合。我也很好奇,与 itertools.combinations.
相比,它是否在幕后有效实施您正在做的是添加一个新轴:"column" 轴。 b
以前没有,所以现在它是一个列向量,将按列添加;它基本上就像在列中重复,并且 a
在行中重复一样:
a+b[:, None] = [1,2] + [[3], = [[1,2], + [[3],[3],
[4]] [1,2]] [4],[4]]
这里是 how/why:
首先要做的事情是:numpy
默认情况下进行元素加法和乘法。这意味着如果 a=np.array([1,2])
那么 a+2=np.array([1+2,2+2])=np.array([3,5])
.
import numpy as np
A = np.array([[1, 2],
[3, 4]])
B = np.array([[1,1],
[0,0]])
这里 A+B
是元素明智的,我们会得到
A+B = [[1+1,2+1], = [[2,3],
[3+0,4+0]] = [3,4]]
如果我们转置矩阵 B
(使用 B.T
)
现在 B.T
将具有值
B.T= np.array([[1,0],
[1,0]])
如果我们这次按元素来做,我们会得到:
A+B.T=[[1, 2] + [[1,0] = [[2,2],
[3, 4]] [1,0]] [4,4]]
另外要注意的是(B
不是转置)
a = np.array([1,2])
B+a = [[1,2], + [[2, 3],
[1,2]] [1, 2]]
它也是按元素排列的,但是在两行上!也就是说 a
实际上是 "repeated" 有两行,并且按元素添加到 B
.
此外,Numpy docs表示None
,在切片中,是另一种写法np.newaxis
。在您的情况下,切片中的 None
选项基本上是在添加之前转置 b
-向量!
import numpy as np
a = np.array([1, 2])
b = np.array([3, 4])
c=a+b.reshape(2,1)
d=a+b.reshape(-1,1)
e=a+b[:, np.newaxis]
此处c
、d
和e
的值相同!
要回答您问题的第一部分,b[:, None]
是一种特殊类型的切片,其行为与 b[:, np.newaxis]
相同,因为它将长度为 1 的轴添加到您的数组中。
>>> b.shape
(2,)
>>> b[:, None].shape
(2, 1)
此行为记录在 numpy
docs [1] 中,强调我的:
The
newaxis
object can be used in all slicing operations to create an axis of length one.newaxis
is an alias forNone
, andNone
can be used in place of this with the same result.
所以现在我们有两个数组:
array([1, 2]) + array([[3],
[4]])
将这两个数组相加得到:
array([[4, 5],
[5, 6]])
这背后的 "magic" numpy
broadcasting[2]. This article [3] 是开始理解该主题的极好资源。
文章的主要内容如下:
numpy
操作通常逐个元素地完成,这需要两个数组具有完全相同的形状。但是,如果两个数组具有相同的尾轴 或者其中一个尾轴等于一个 (这是在你的案例中表现出的行为)。
在您的例子中,发生了广播,因此该操作等效于对以下 2x2 数组求和:
array([[1, 2], + array([[3, 3],
[1, 2]]) [4, 4]])
由于 numpy 操作是逐个元素完成的,因此将产生所需的输出:
array([[4, 5],
[5, 6]])
[1]https://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#numpy.newaxis
[2]https://docs.scipy.org/doc/numpy-1.13.0/user/basics.broadcasting.html
[3]http://scipy.github.io/old-wiki/pages/EricsBroadcastingDoc