我在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矢量来制作矩阵,我迷路了。
您能帮助我理解或提高此代码的可读性吗?
答案 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