2D 数组每列的外积形成 3D 数组 - NumPy
Posted
技术标签:
【中文标题】2D 数组每列的外积形成 3D 数组 - NumPy【英文标题】:Outer product of each column of a 2D array to form a 3D array - NumPy 【发布时间】:2017-05-19 02:06:48 【问题描述】:令 X 为 M x N 矩阵。将 xi 表示为 X 的第 i 列。我想创建一个由 M x M 矩阵xi.dot(xi.T)
组成的 3 维 N x M x M 数组。
我怎样才能用 numpy 最优雅地做到这一点?是否可以仅使用矩阵运算而不使用循环来做到这一点?
【问题讨论】:
听起来像是 np.einsum 的工作。 @Divakar 谢谢,已编辑。现在 X 是 M x N 矩阵。 似乎 (rows,cols) 在这里混淆了...要使用具体数字,假设我们从 (Mrows, Ncols) = (2,3) 开始。 OP 正在使用列向量操作Ni*Ni.T
。每列的长度为 Mrows=2,因此乘积产生一个 (2,2) 矩阵 - 即 (Mrows,Mrows)。对每一列执行此操作并将结果堆叠在第三维中应该会产生一个 (M x M x N) 矩阵。
@MattP OP 可能正在沿第一轴堆叠/存储:for i in range(N): out[i] = X[:,i,None].dot(X[None,:,i])
。
@Divakar 那是一些非常好的广播/索引!我今天在这里学到了一些新东西。我自己(不那么花哨,更循环,并且可能性能较差)对这个问题给出相同结果的解决方案是:Result = np.dstack( X[:,i].reshape((nrows,1)) * X[:,i] for i in range(ncols) )
。
【参考方案1】:
broadcasting
的一种方法-
X.T[:,:,None]*X.T[:,None]
另一个 broadcasting
之后交换轴 -
(X[:,None,:]*X).swapaxes(0,2)
另一个是broadcasting
,之后是一个多维转置-
(X[:,None,:]*X).T
np.einsum
的另一种方法,如果您从循环代码中翻译,就所涉及的迭代器而言,这可能更直观 -
np.einsum('ij,kj->jik',X,X)
所有这些方法的基本思想是,我们散布最后一个轴,以便相互进行元素乘法,保持第一个轴对齐。我们通过将X
扩展为两个3D
数组版本来实现相互对抗的过程。
【讨论】:
以上是关于2D 数组每列的外积形成 3D 数组 - NumPy的主要内容,如果未能解决你的问题,请参考以下文章