如何在numpy中获得逐元素矩阵乘法(Hadamard积)?

173

我有两个矩阵

a = np.matrix([[1,2], [3,4]])
b = np.matrix([[5,6], [7,8]])

我想要获得逐元素相乘的结果,[[1*5,2*6], [3*7,4*8]], 等于

[[5,12], [21,32]]

我已经尝试过了

print(np.dot(a,b)) 

print(a*b)

但两者都会给出结果。

[[19 22],[43 50]]

这是矩阵乘积,而不是逐元素相乘。如何使用内置函数获取逐元素乘积(又称为Hadamard乘积)?


7
你确定 ab 不是 NumPy 的矩阵类型吗?使用这个类,* 返回的是内积而不是逐元素相乘。但对于通常的 ndarray 类,* 表示逐元素相乘。 - bnaecker
ab是numpy数组吗?此外,在您上面的问题中,计算时使用了xy而不是ab,这只是一个打字错误吗? - jtitusj
a和b是numpy矩阵类型的元素。 - Malintha
9
始终使用numpy数组,而不是numpy矩阵。请参见numpy文档中的内容。此外,请注意从python 3.5+开始,您可以使用numpy数组的@矩阵乘法,这意味着没有任何好理由使用矩阵而不是数组。 - Praveen
3
挑剔一点,ab是列表。它们可以在np.dot中使用,但不能在a*b中使用。如果您使用np.array(a)np.matrix(a),则*可以使用,但结果不同。 - hpaulj
如果您使用 np.array(a)np.array(b),那么简单的 a*b 就可以工作了。请注意,如果数字很大,您应该使用 np.array(a, dtype=np.int64) 来获得正确的输出。 - Ehsan Tabatabaei
4个回答

249

对于矩阵对象的逐元素乘法,您可以使用numpy.multiply函数:

import numpy as np
a = np.array([[1,2],[3,4]])
b = np.array([[5,6],[7,8]])
np.multiply(a,b)

结果

array([[ 5, 12],
       [21, 32]])

然而,你应该使用array而不是matrixmatrix对象与常规的ndarrays存在各种可怕的不兼容性。对于ndarrays,您可以只需使用*进行逐元素乘法:
a * b

如果您使用的是Python 3.5+,甚至可以使用运算符@来进行矩阵乘法,因为它现在已经支持了:

a @ b  # matrix multiplication

32
补充一些背景信息:在代数学中,这个运算被称为Hadamard积,与更常见的矩阵乘积不同。详细请参考维基百科:https://en.wikipedia.org/wiki/Hadamard_product_(matrices) - FaCoffee

40

只需要这样做:

import numpy as np

a = np.array([[1,2],[3,4]])
b = np.array([[5,6],[7,8]])

a * b

2
nop,它给出了矩阵乘法。可以使用numpy.multiply在云端解决它。 - Malintha
很奇怪。np.multiply 也可以完成这个任务,但我不知道为什么 a * b 对你不起作用。 - jtitusj
2
你使用的是哪个版本和小版本的Python?还有numpy呢? - smci
3
使用Intel Python 3.5.2和numpy 1.12.1,*运算符似乎进行逐元素乘法。 - apnorton
1
这对我来说也适用于使用gcc编译的Python 3.5.2上的Numpy 1.12.1。 - Sandeep Datta
9
@Malintha,我认为你正在执行的是a = np.matrix([[1,2],[3,4]]),而不是... - SeF

19
import numpy as np
x = np.array([[1,2,3], [4,5,6]])
y = np.array([[-1, 2, 0], [-2, 5, 1]])

x*y
Out: 
array([[-1,  4,  0],
       [-8, 25,  6]])

%timeit x*y
1000000 loops, best of 3: 421 ns per loop

np.multiply(x,y)
Out: 
array([[-1,  4,  0],
       [-8, 25,  6]])

%timeit np.multiply(x, y)
1000000 loops, best of 3: 457 ns per loop

无论是np.multiply还是*都会产生逐元素相乘,也被称为Hadamard乘积。

%timeit是ipython的魔法方法。


1

试试这个:

a = np.matrix([[1,2], [3,4]])
b = np.matrix([[5,6], [7,8]])

#This would result a 'numpy.ndarray'
result = np.array(a) * np.array(b)

在这里,np.array(a)返回一个类型为ndarray的二维数组,两个ndarray的乘积会得到逐元素相乘的结果。因此结果将是:
result = [[5, 12], [21, 32]]

如果你想要一个矩阵,那就用这个:

result = np.mat(result)

请解释这是做什么的。 - Leopold Joy
2
@LeopoldJoy 我刚刚编辑了我的回答,希望这能帮到你 :)) - amrezzd

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