求两个矩阵所有列组合的逐元素积,能否不使用np.hstack?
解决方案:无需
hstack的实现方式 当然可以去掉hstack!其实只需要调整数组维度的处理逻辑,就能直接生成目标的d×(n*m)矩阵,不用额外做横向拼接操作。这里有几种简洁的实现方案:
方法1:调整einsum下标 + reshape
直接修改einsum的输出维度顺序,再通过reshape合并列组合维度:
import numpy as np # 示例矩阵 a = np.array([[1, 2], [3, 4]]) # d=2, n=2 b = np.array([[5, 6], [7, 8]]) # d=2, m=2 # 无需hstack的实现 result = np.einsum('dj, dl -> djl', a, b).reshape(a.shape[0], -1)
解释:
'dj, dl -> djl':指定将a(d行n列)和b(d行m列)按行维度d对齐,计算每一列组合的逐元素积,输出维度为d×n×m。.reshape(a.shape[0], -1):将最后两个维度n和m合并为一维,直接得到d×(n*m)的目标矩阵,和你原来用hstack的结果完全一致。
方法2:利用广播机制 + reshape
如果觉得einsum的下标有点绕,也可以用numpy的广播特性实现:
result = (a[:, :, None] * b[:, None, :]).reshape(a.shape[0], -1)
解释:
a[:, :, None]:将a从d×n扩展为d×n×1,b[:, None, :]将b从d×m扩展为d×1×m。- 广播后相乘会自动匹配维度,得到
d×n×m的逐元素积数组,再通过reshape合并维度即可。
方法3:更紧凑的einsum写法
numpy的einsum支持直接合并维度(主流版本均支持),可以一步到位:
result = np.einsum('dj, dl -> d(jl)', a, b)
这里(jl)表示将j和l维度合并为一维,直接输出d×(n*m)的矩阵,连reshape都省了。
验证结果一致性
你可以对比原方法和新方法的输出:
# 原方法 original_result = np.hstack(np.einsum('...j,...l -> j...l', a, b)) print(np.array_equal(result, original_result)) # 输出True,说明结果完全一致
内容的提问来源于stack exchange,提问作者paul
相关产品推荐
相关产品推荐

