如何对标量矩阵和向量矩阵进行逐元素相乘?

4
如何将以下形式的numpy数组A转换为中文:

[[1,2]
 [3,4]]

“into B的形式”
[[[1,1,1],[2,2,2]]
 [[3,3,3],[4,4,4]]]

这样我就可以对C进行逐元素乘法操作。
[[[ 5, 6, 7],[ 8, 9,10]]
 [[11,12,13],[13,15,16]]]

原文中的

?

是一个HTML标签,表示一个段落。
原始问题是将标量与向量相乘,例如4 * [13,15,16]。但是,我有一个标量矩阵(A)和一个向量矩阵(C),而不是一个向量。如果有一种方法可以避免像B那样复制值,我会更喜欢它(显然,使用for循环会太慢了)。

2
嗯,我想我明白了:A[:,:,None] * C 但我还没有完全理解这里发生了什么。 - letmaik
3
您还可以执行 A[..., None] * C,这不仅适用于两个维度,而是适用于任意数量的维度。 - Jaime
2
@neo,这里发生的是你发现了广播 :) - askewchan
1个回答

3
你已经在评论中提到了答案:

A[:,:,None] * C

这个方法的原因是因为numpy把None切片解释为newaxis。来自文档的说明如下:

选择元组中每个newaxis对象都可以通过一个单位长度的维度扩展结果选择的维度。新增加的维度是选择元组中newaxis对象的位置。

因此,这个切片等同于执行以下操作:
A.reshape(len(A), -1, 1)*C

我假设这些是numpy array,因此默认情况下乘法当然是逐元素进行的。


更多信息请参见广播 - askewchan
1
“reshape”不会修改“A”,因此最终的示例仍会出现广播错误。也许你的意思是:A.reshape(len(A), -1, 1)*C,这将给出等效的结果。 - askewchan
啊,你说得对。我甚至在执行那个操作时还开着 REPL。=X 已修复。 - Free Monica Cellio
仅供文档参考:A[:,:,None] 将产生 [[[1],[2]],[[3],[4]]],因此其形状为 (2,2,1),这使得它可以广播到 C 的形状 (2,2,3),从而实现乘法 - 因为广播隐式地通过重复值(不是字面上的重复,而是在 for 循环中内部重复)将 (2,2,1) 扩展为 (2,2,3) - letmaik
还有一件事。我想我明白了为什么我的示例不能简单地工作,尽管较简单的情况确实可以(标量和向量)。这可能是因为在广播时标量被特殊处理,并且等同于形状为(1)的单元素数组,从而导致有效的广播。因此,如果我将A中的标量表示为给定矩阵内的单元素数组,它就会正常工作。这更多是一个理论观点,但仍然很有趣。 - letmaik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接