Python 对成对操作使用“无”的numpy索引

Python 对成对操作使用“无”的numpy索引,python,numpy,array-broadcasting,numpy-ndarray,Python,Numpy,Array Broadcasting,Numpy Ndarray,如果我有两个像这样的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,2+4的结果 为什么这样做有效?“没有”在做什么?我可以打印出来 b[:, None] [[3] [4]] 但我不知道为什么这会让numpy做成对组合。我也很好奇,与itertools.compo

如果我有两个像这样的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,2+4的结果

为什么这样做有效?“没有”在做什么?我可以打印出来

b[:, None]
[[3]
 [4]]

但我不知道为什么这会让numpy做成对组合。我也很好奇,与itertools.compositions相比,它是否能有效地在引擎盖下实现。

您正在做的是添加一个新的轴:柱轴。b以前没有,所以现在它是一个列向量,可以按列添加;基本上,它的作用就像在列中重复,在行中重复:

a+b[:, None] = [1,2] + [[3], = [[1,2], + [[3],[3],
                        [4]]    [1,2]]    [4],[4]]
以下是如何/为什么:

第一件事:默认情况下,numpy执行元素级的加法和乘法。这意味着如果a=np.array[1,2],那么a+2=np.array[1+2,2+2]=np.array[3,5]

这里A+B是元素方面的,我们得到

A+B = [[1+1,2+1], = [[2,3],
       [3+0,4+0]] =  [3,4]]
如果我们用B.T变换矩阵B

现在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实际上被重复了两行,并将元素添加到B

此外,None表示,在切片中,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)
这一行为记录在矿山重点中:

newaxis对象可用于所有切片操作,以创建长度为1的轴。newaxis是None的别名,可以使用None来代替None,并获得相同的结果

现在我们有两个数组:

array([1, 2]) + array([[3],
                       [4]])
将这两个数组相加可得出:

array([[4, 5],
       [5, 6]])
这背后的魔力是。是开始理解主题的极好资源

文章的主要内容如下:

numpy操作通常是逐元素进行的,这需要两个数组具有完全相同的形状。但是,如果两个阵列具有相同的尾随轴,或者如果其中一个尾随轴等于案例中显示的行为,则此约束将被放宽

在您的情况下,会发生广播,因此该操作相当于对以下2x2阵列求和:

array([[1, 2],    +  array([[3, 3],
       [1, 2]])            [4, 4]])
由于numpy操作是逐元素完成的,因此将产生以下所需的输出:

array([[4, 5],
       [5, 6]])
[1]

[2]


[3]

您正在广播的还有您的问题,为什么b[:,None]返回带有形状2,1的数组,或者为什么添加2,形状数组和2,1形状数组会产生这样的结果。我猜,看看b.shape和b[:,None].shape。谢谢!这篇文章很有帮助。如果你愿意的话,把它作为答案贴出来?
array([[4, 5],
       [5, 6]])