python 添加具有不同维数的数组

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2104643/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 23:47:17  来源:igfitidea点击:

Adding arrays with different number of dimensions

pythonnumpy

提问by astrofrog

Let's say I have a 2D Numpy array:

假设我有一个 2D Numpy 数组:

>>> a = np.random.random((4,6))

and I want to add a 1D array to each row:

我想为每一行添加一个一维数组:

>>> c = np.random.random((6,))
>>> a + c

This works. Now if I try adding a 1D array to each column, I get an error:

这有效。现在,如果我尝试向每列添加一个一维数组,则会出现错误:

>>> b = np.random.random((4,))
>>> a + b
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: shape mismatch: objects cannot be broadcast to a single shape

I can fix this by using np.newaxis:

我可以使用np.newaxis以下方法解决此问题:

>>> a + b[:,np.newaxis]

which does work as expected.

这确实按预期工作。

What are the shape-matching rules to avoid having to use np.newaxis? Is it that the last element of the numpy shape tuple has to match? Does this rule also apply to higher dimensions? For example, the following works:

避免使用 np.newaxis 的形状匹配规则是什么?numpy 形状元组的最后一个元素是否必须匹配?这个规则是否也适用于更高的维度?例如,以下工作:

>>> a = np.random.random((2,3,4,5))
>>> b = np.random.random((4,5))
>>> a + b

So my question is whether this is documented anywhere, and if it is a behavior that can be relied on, or whether it is best to always use np.newaxis?

所以我的问题是这是否在任何地方都有记录,是否是可以依赖的行为,或者是否最好始终使用 np.newaxis?

回答by Antony Hatchkins

This is a distinctive feature of numpy called broadcasting. It is done using four rules which are a bit complicated in formulation but are rather intuitive once understood:

这是 numpy 的一个显着特征,称为广播。它是使用四个规则完成的,这些规则在表述上有点复杂,但一旦理解就相当直观:

  1. All input arrays with ndimsmaller than the input array of largest ndim, have 1's prepended to their shapes.
  2. The size in each dimension of the output shape is the maximum of all the input sizes in that dimension.
  3. An input can be used in the calculation if its size in a particular dimension either matches the output size in that dimension, or has value exactly 1.
  4. If an input has a dimension size of 1 in its shape, the first data entry in that dimension will be used for all calculations along that dimension. In other words, the stepping machinery of the ufuncwill simply not step along that dimension (the stride will be 0 for that dimension).
  1. 所有ndim小于最大输入数组的输入数组ndim都在其形状前加上 1。
  2. 输出形状的每个维度的大小是该维度中所有输入大小的最大值。
  3. 如果输入在特定维度中的大小与该维度中的输出大小匹配,或者其值恰好为 1,则可以在计算中使用该输入。
  4. 如果输入的形状的维度大小为 1,则该维度中的第一个数据条目将用于沿该维度的所有计算。换句话说, 的步进机器ufunc不会沿着那个维度前进(该维度的步幅将为 0)。

The operation is possible (doesnt result in shape mismatcherror you mentioned) in three cases:

该操作shape mismatch在三种情况下是可能的(不会导致您提到的错误):

  1. The arrays all have exactly the same shape.
  2. The arrays all have the same number of dimensions and the length of each dimensions is either a common length or 1.
  3. The arrays that have too few dimensions can have their shapes prepended with a dimension of length 1 to satisfy property 2.
  1. 阵列都具有完全相同的形状。
  2. 数组都具有相同的维数,每个维的长度要么是公共长度,要么是 1。
  3. 维数太少的数组可以在其形状前面加上长度为 1 的维以满足属性 2。

Examples can be found via the link above.

可以通过上面的链接找到示例。

回答by telliott99

Let me see if I get it...

让我看看我能不能收到...

>>> from numpy import ones, newaxis
>>> A = ones((4,3))   # 4 rows x 3 cols
>>> A.shape
(4, 3)
>>> A
array([[ 1.,  1.,  1.],
       [ 1.,  1.,  1.],
       [ 1.,  1.,  1.],
       [ 1.,  1.,  1.]])
>>> 
>>> ones((4,1))      # 4 rows x 1 col
array([[ 1.],
       [ 1.],
       [ 1.],
       [ 1.]])
>>> A + ones((4,1))
array([[ 2.,  2.,  2.],
       [ 2.,  2.,  2.],
       [ 2.,  2.,  2.],
       [ 2.,  2.,  2.]])
>>> 
>>> ones((1,3))      # 1 row x 3 cols
array([[ 1.,  1.,  1.]])
>>> A + ones((1,3))  
array([[ 2.,  2.,  2.],
       [ 2.,  2.,  2.],
       [ 2.,  2.,  2.],
       [ 2.,  2.,  2.]])
>>> 
>>> B = ones((3,))   # a 1D array
>>> B
array([ 1.,  1.,  1.])
>>> B.shape
(3,)
>>> A + B
array([[ 2.,  2.,  2.],
       [ 2.,  2.,  2.],
       [ 2.,  2.,  2.],
       [ 2.,  2.,  2.]])
>>> 
>>> C = ones((4,))   # a 1D array
>>> C.shape
(4,)
>>> C
array([ 1.,  1.,  1.,  1.])
>>> A + C
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: shape mismatch: objects cannot be broadcast to a single shape
>>> 
>>> D = C[:,newaxis]
>>> D.shape
(4, 1)
>>> A + D
array([[ 2.,  2.,  2.],
       [ 2.,  2.,  2.],
       [ 2.,  2.,  2.],
       [ 2.,  2.,  2.]])

The broadcast needed to do 4 x 3 vector plus a 1D vector with 3 elements succeeds.

广播需要做 4 x 3 向量加上具有 3 个元素的 1D 向量成功。

The broadcast needed to do 4 x 3 vector plus a 1D vector with 4 elements fails.

需要做 4 x 3 向量加上具有 4 个元素的 1D 向量的广播失败。

>>> D = C[:,newaxis]

converts C to a 2D vector of a compatible shape.

将 C 转换为具有兼容形状的二维向量。