首页 > 解决方案 > 使用“无”进行成对操作的 numpy 索引

问题描述

如果我有两个看起来像这样的 numpy 数组

a = np.array([1, 2])
b = np.array([3, 4])

我想添加所有成对组合,我可以轻松做到

c = a + b[:, None]
c
array([[4, 5],
       [5, 6]])

得到1+3 , 2+31+4 , 2+4的结果。

为什么这行得通?“无”在做什么?我可以打印出来

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

但我不确定为什么这会告诉 numpy 进行成对组合。与 itertools.combinations 相比,我也很好奇它是否在后台有效实施。

标签: pythonnumpyarray-broadcastingnumpy-ndarray

解决方案


要回答您问题的第一部分,b[:, None]是一种特殊类型的切片,它具有与 相同的行为b[:, np.newaxis],因为它将长度为 1 的轴添加到您的数组中。

>>> b.shape
(2,)
>>> b[:, None].shape
(2, 1)

这种行为记录在numpy文档[1]中,强调我的:

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

所以现在我们有两个数组:

array([1, 2]) + array([[3],
                       [4]])

将这两个数组相加得到:

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

这背后的“魔力”就是numpy广播[2]本文[3]是开始理解该主题的绝佳资源。


文章的主要内容如下:

numpy操作通常是逐个元素完成的,这需要两个数组具有完全相同的形状。但是,如果两个数组具有相同的尾轴,或者如果其中一个尾轴等于 1(这是您的案例中表现出的行为),则此约束会被放宽。

在您的情况下,会发生广播,因此该操作相当于对以下 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


推荐阅读