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的主要内容,如果未能解决你的问题,请参考以下文章

R语言中两个数组(或向量)的外积怎样计算

如何以某种并行的方式有效地计算两个数组列表的外积?

Python numpy 2D数组最小值

获取二维数组中每列的第二个最小值

矩阵运算相关函数

Java求解! 定义一个6行6列的二维整型数组,输出该二维数组中的每行和每列的最大值、最小值、和平均值。