numpy:水平播放矢量

时间:2017-06-30 03:21:05

标签: numpy numpy-broadcasting

我在numpy v中有一个一维数组。我想复制它以制作一个矩阵,每行都是v的副本。这很简单:np.broadcast_to(v, desired_shape)

但是,如果我想将v视为向量,并将其复制以制作矩阵,每个为副本v,我找不到一个简单的方法来做到这一点。通过反复试验,我能够做到这一点:

 np.broadcast_to(v.reshape(v.shape[0], 1), desired_shape)

虽然这有效,但我无法理解它(即使我写了它!)。

部分问题是numpy似乎没有列向量的概念(因此reshape hack而不是数学中的.T}。

但是,问题的更深层次似乎是广播只能垂直工作,而不能横向工作。或者也许是一种更正确的说法:广播只适用于较高维度,而不是较低维度。 我甚至不确定这是否正确。

简而言之,虽然我一般都理解广播的概念,但当我尝试将它用于特定应用时,比如复制col矢量来制作矩阵,我迷路了。

您能帮助我理解或提高此代码的可读性吗?

2 个答案:

答案 0 :(得分:1)

https://en.wikipedia.org/wiki/Transpose - 关于Transpose的这篇文章只谈到转置矩阵。

https://en.wikipedia.org/wiki/Row_and_column_vectors -

  

列向量或列矩阵是m×1矩阵   行向量或行矩阵是1×m矩阵

您可以轻松创建行或列向量(矩阵):

In [464]: np.array([[1],[2],[3]])   # column vector
Out[464]: 
array([[1],
       [2],
       [3]])
In [465]: _.shape
Out[465]: (3, 1)

In [466]: np.array([[1,2,3]])  # row vector
Out[466]: array([[1, 2, 3]])
In [467]: _.shape
Out[467]: (1, 3)

但在numpy中,基本结构是array,而不是矢量或矩阵。

  

[计算机科学中的数组] - 通常,可以通过在运行时计算的索引选择的数据项集合

numpy数组可以包含0个或更多维度。相比之下,MATLAB矩阵有2个或更多维度。最初是一个2D矩阵就是MATLAB所拥有的。

要有意义地谈论转置,你必须至少有2个维度。一个可能有一个大小,并映射到一个矢量,但它仍然是一个矩阵,一个2d对象。

因此,无论是使用reshape还是[:,None],都可以向1d数组添加维度。这是一个完美有效和正常的numpy操作。

基本广播规则是:

  • 可以更改尺寸为1的尺寸以匹配其他数组的相应尺寸

  • 尺寸1的尺寸可以自动添加到左侧(正面)以匹配尺寸数。

在此示例中,两个步骤都适用:(5,)=>(1,5)=>(3,5)

In [458]: np.broadcast_to(np.arange(5), (3,5))
Out[458]: 
array([[0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4]])

在此,我们必须在右侧(结束)明确添加一个尺寸:

In [459]: np.broadcast_to(np.arange(5)[:,None], (5,3))
Out[459]: 
array([[0, 0, 0],
       [1, 1, 1],
       [2, 2, 2],
       [3, 3, 3],
       [4, 4, 4]])

np.broadcast_arrays(np.arange(5)[:,None], np.arange(3))生成两个(5,3)数组。

np.broadcast_arrays(np.arange(5), np.arange(3)[:,None])使(3,5)。

np.broadcast_arrays(np.arange(5), np.arange(3))会产生错误,因为它无法确定您是否需要(5,3)或(3,5)或其他内容。

答案 1 :(得分:0)

广播总是在左边添加新的尺寸,因为当你想要新的尺寸在右边时,它会模糊不清并容易出错。您可以通过反转轴,广播和反转来使功能向右广播:

def broadcast_rightward(arr, shape):
    return np.broadcast_to(arr.T, shape[::-1]).T