首页 > 解决方案 > numpy 广播 - 尾轴的解释

问题描述

问题

请详细说明2012 年Numpy 数组广播规则中的答案,并澄清什么是尾轴,因为我不确定答案指的是哪个“链接文档页面”。也许它在过去 8 年里发生了变化。

由于trailing axes复数,因此至少最后两个轴大小必须匹配(单数除外)?如果是这样,为什么至少有两个?

给出的答案是:

好吧,在链接的文档页面上解释了尾轴的含义。如果您有两个具有不同维数的数组,例如一个 1x2x3 和另一个 2x3,那么您只比较尾随的公共维度,在本例中为 2x3。但是,如果您的两个数组都是二维的,那么它们对应的大小必须相等或者其中一个必须是 1

在您的情况下,您有 2x2 和 4x2 和 4 != 2 并且 4 或 2 都不等于 1,所以这不起作用。

错误和提出的问题是:

A = np.array([[1,2],[3,4]])
B = np.array([[2,3],[4,6],[6,9],[8,12]])
print("A.shape {}".format(A.shape))
print("B.shape {}".format(B.shape))
A*B
---
A.shape (2, 2)              # <---- The last axis size is 2 in both shapes.
B.shape (4, 2)              # <---- Apparently this "2" is not the size of trailing axis/axes

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-91-7a3f7e97944d> in <module>
      3 print("A.shape {}".format(A.shape))
      4 print("B.shape {}".format(B.shape))
----> 5 A*B

ValueError: operands could not be broadcast together with shapes (2,2) (4,2) 


Since both A and B have two columns, I would have thought this would work. 
So, I'm probably misunderstanding something here about the term "trailing axis", 
and how it applies to N-dimensional arrays.

参考

广播规则
为了广播,一个操作中两个数组的尾轴的大小必须相同,或者其中之一必须是一个。


更新

根据@Akshay Sehgal 的回复理解。考虑 2 个数组 A.shape = (4,5,1) 和 B.shape = (1,2)。

A = np.arange(20).reshape((4, 5, 1))
B = np.arange(2).reshape((1,2))
print("A.shape {}".format(A.shape))
print("B.shape {}".format(B.shape))
---
A.shape (4, 5, 1)
B.shape (1, 2)

首先看axis=-1,A中的形状01是从01广播到02的,因为它是奇异的,为了匹配B的形状。然后B中的形状01对于axis=-2从01(单数)广播到05 以匹配 A。结果是形状 (4, 5, 2)。

print("A * B shape is {}".format((A*B).shape))
---
A * B shape is (4, 5, 2)

基于@hpaulj 的回答,一种模拟广播的方法。

print("A.shape {}".format(A.shape))
print("B.shape {}".format(B.shape))
---
A.shape (4, 5, 1)
B.shape (1, 2)

# Check ranks.
print("rank(A) {} rank(B) {}".format(A.ndim, B.ndim))
---
rank(A) 3 rank(B) 2

# Expand B because rank(B) < rank(A).
B = B[
    None,
    ::
]
B.shape
---
(1, 1, 2)

A:(4,5,1)
   ↑ ↑ ↓
B:(1,1,2)
----------
C:(4,5,2)

标签: pythonnumpyarray-broadcasting

解决方案


拖尾轴是axis=-1, axis=-2, axis=-3 .... 广播规则比较尾随轴与leading轴(axis=0向前)。

这专门用于将广播应用于不同维度的张量(例如 2D 和 3D 张量)。Trailing axes基本上表示广播规则考虑轴的方向。想象一下按形状排列轴。如果您lead使用轴,您将拥有以下内容 -

考虑2个数组A.shape = (4,5,1)B.shape = (1,2)

#Leading axes

A  04  05  01
B  01  02
--------------
No broadcasting
--------------

要考虑尾随轴,您会将它们视为 -

#Trailing axes

A  04  05  01
B      01  02
--------------
C  04  05  02
--------------

这就是他们在这种情况下使用该术语的全部含义,trailing axes即向后而不是引导轴开始。

换句话说,当考虑广播一个(1,2)具有更高维数组的成形数组时,我们会查看已成形的拖尾轴,2 for axis=-1然后1 for axis=-2以相反的顺序查看。


推荐阅读