Arrays 如何分别用其它元素运算和归约运算代替np.dot中的乘法和和运算
假设您有两个相对较大的数组Arrays 如何分别用其它元素运算和归约运算代替np.dot中的乘法和和运算,arrays,performance,numpy,Arrays,Performance,Numpy,假设您有两个相对较大的数组a和b。您可以使用广播制作dot产品: a = np.random.normal(size=(1000, 300)) b = a*2 ref = a.dot(b.T) res = (a[:,None,:]*b[None,:,:]).sum(2) np.allclose(ref, res) # True timeit -n 1 -r 5 a.dot(b.T) # 17.6 ms timeit -n 1 -r 5 (a[:,None,:]*b[None,:,:]
a
和b
。您可以使用广播制作dot
产品:
a = np.random.normal(size=(1000, 300))
b = a*2
ref = a.dot(b.T)
res = (a[:,None,:]*b[None,:,:]).sum(2)
np.allclose(ref, res)
# True
timeit -n 1 -r 5 a.dot(b.T)
# 17.6 ms
timeit -n 1 -r 5 (a[:,None,:]*b[None,:,:]).sum(2)
# 1.83 s
性能差异大约为2个数量级,更大的阵列甚至更大。
np.dot
速度快得多,因为它使用专门的库,但也因为它不在内存中存储完整的时态数组a[:,None,:]*b[None,:,:,:]
np.dot
总是先进行乘法运算,然后进行求和运算。我想知道是否有可能用任何其他元素操作(如np.max
,==
,np.power
…)代替乘法运算,并用其他还原操作(如np.max
)代替求和运算。我知道这将有利基现实世界的应用,但我认为它在某些情况下可能是有用的
我尝试过使用numexpr
,但它对func和dtype的支持有限
我还尝试过使用自定义乘法和求和方法,使用dype=object
创建一个数组,但这样就不再处理连续的内存块了
在numpy有什么有效的方法来实现这一点吗
理想情况下,使用syntax的函数:
np.custom\u dot(a,b,elementwise\u func=my\u func,redux\u func=my\u other\u func)
您不能编写自己的专用库吗?也许以cython为起点。@hpaulj我已经用cython做过几次简单的事情(我经常得到这个)。我希望有一个更简单的纯numpy
解决方案这听起来像是numba()最适合的解决方案。原始的np.einsum
(现在包含在c\u einsum
函数中)使用cython和nditer
对维度的复杂组合执行乘积和。几年前我写了一篇关于省略号用法的补丁时,我深入研究了这个问题。当时还有一个问题,要求使用其他对运算符的einsum
。np.nditer
对性能没有帮助,但如图所示,可以作为在cython中使用它的垫脚石。np.einsum('ij,kj',a,b,optimize=True)
提供与点相同的计时np.einsum('ij,kj',a,b,optimize=False)
使用原始(nditer)版本您可以编写自己的专用库吗?也许以cython为起点。@hpaulj我已经用cython做过几次简单的事情(我经常得到这个)。我希望有一个更简单的纯numpy
解决方案这听起来像是numba()最适合的解决方案。原始的np.einsum
(现在包含在c\u einsum
函数中)使用cython和nditer
对维度的复杂组合执行乘积和。几年前我写了一篇关于省略号用法的补丁时,我深入研究了这个问题。当时还有一个问题,要求使用其他对运算符的einsum
。np.nditer
对性能没有帮助,但如图所示,可以作为在cython中使用它的垫脚石。np.einsum('ij,kj',a,b,optimize=True)
提供与点相同的计时<代码>np.einsum('ij,kj',a,b,optimize=False)使用原始(nditer)版本