根据此question的答案,也根据numpy,与a @ b
或numpy.matmul(a,b)
相比,二维数组的矩阵乘法最好与a.dot(b)
。
如果a和b均为二维数组,则为矩阵乘法,但使用 最好是matmul或a @ b。
我做了以下基准测试,发现相反的结果。
问题:我的基准测试有问题吗?如果不是,为什么Numpy在比a.dot(b)
或a@b
快的情况下不推荐numpy.matmul(a,b)
?
基准使用python 3.5 numpy 1.15.0。
$ pip3 list | grep numpy
numpy 1.15.0
$ python3 --version
Python 3.5.2
基准代码:
import timeit
setup = '''
import numpy as np
a = np.arange(16).reshape(4,4)
b = np.arange(16).reshape(4,4)
'''
test = '''
for i in range(1000):
a @ b
'''
test1 = '''
for i in range(1000):
np.matmul(a,b)
'''
test2 = '''
for i in range(1000):
a.dot(b)
'''
print( timeit.timeit(test, setup, number=100) )
print( timeit.timeit(test1, setup, number=100) )
print( timeit.timeit(test2, setup, number=100) )
结果:
test : 0.11132473500038031
test1 : 0.10812476599676302
test2 : 0.06115105600474635
添加结果:
>>> a = np.arange(16).reshape(4,4)
>>> b = np.arange(16).reshape(4,4)
>>> a@b
array([[ 56, 62, 68, 74],
[152, 174, 196, 218],
[248, 286, 324, 362],
[344, 398, 452, 506]])
>>> np.matmul(a,b)
array([[ 56, 62, 68, 74],
[152, 174, 196, 218],
[248, 286, 324, 362],
[344, 398, 452, 506]])
>>> a.dot(b)
array([[ 56, 62, 68, 74],
[152, 174, 196, 218],
[248, 286, 324, 362],
[344, 398, 452, 506]])
答案 0 :(得分:3)
您的前提不正确。您应该使用更大的矩阵来衡量性能,以避免函数调用使无关紧要的计算相形见。
使用Python 3.60 / NumPy 1.11.3,您将发现@
调用np.matmul
,并且都胜过np.dot
,如here所述。
import numpy as np
n = 500
a = np.arange(n**2).reshape(n, n)
b = np.arange(n**2).reshape(n, n)
%timeit a.dot(b) # 134 ms per loop
%timeit a @ b # 71 ms per loop
%timeit np.matmul(a,b) # 70.6 ms per loop
还要注意,如文档中所述,np.dot
在功能上与@
/ np.matmul
不同。特别是,它们在处理尺寸大于2的矩阵方面有所不同。
答案 1 :(得分:0)
matmul
和dot
做的事情不同。它们在3D数组和标量上的行为有所不同。该文档可能会指出matmul
是首选,因为它更“清晰”且通用,不一定出于性能原因。如果文档能更清楚地说明为什么一个优先于另一个,那就太好了。
正如@jpp所指出的那样,matmul
的性能实际上并不一定会变差。