我有一个numpy的操作,我称之为集中,我需要优化:聚合numpy的功能
np.sum(a**2, axis=1)**.5 # where a is a 2 dimensional ndarray
这一操作是由三个功能,需要通过“A”三次迭代。将一个功能下的所有操作聚合在一起并沿轴1使用该功能会更有效率。不幸的是,numpy的apply_along_axis功能不是一种选择,因为性能在x1000左右更差。
有没有聚合几个numpy操作的方法,所以它只需要在数组上循环一次?
我有一个numpy的操作,我称之为集中,我需要优化:聚合numpy的功能
np.sum(a**2, axis=1)**.5 # where a is a 2 dimensional ndarray
这一操作是由三个功能,需要通过“A”三次迭代。将一个功能下的所有操作聚合在一起并沿轴1使用该功能会更有效率。不幸的是,numpy的apply_along_axis功能不是一种选择,因为性能在x1000左右更差。
有没有聚合几个numpy操作的方法,所以它只需要在数组上循环一次?
当浮点阵列时,您可以使用np.einsum
-
np.sqrt(np.einsum('ij,ij->i',a,a))
运行测试 -
In [34]: a = np.random.rand(1000,1000)
In [35]: np.allclose(np.sum(a**2, axis=1)**.5,np.sqrt(np.einsum('ij,ij->i',a,a)))
Out[35]: True
In [36]: %timeit np.sum(a**2, axis=1)**.5
100 loops, best of 3: 7.57 ms per loop
In [37]: %timeit np.sqrt(np.einsum('ij,ij->i',a,a))
1000 loops, best of 3: 1.52 ms per loop
看看numexpr
,它可以让你更快的计算数值表达式比纯numpy
:
In [19]: a = np.arange(1e6).reshape(1000,1000)
In [20]: import numexpr as ne
In [21]: %timeit np.sum(a**2,axis=1)**0.5
100 loops, best of 3: 6.08 ms per loop
In [22]: %timeit ne.evaluate("sum(a**2,axis=1)")**0.5
100 loops, best of 3: 4.27 ms per loop
的**0.5
不是表达式的一部分,因为sum
是还原操作,需要计算的最后在表达式中。您还可以对sqrt
/**0.5
运行另一项评估。
'numexpr'为'sqrt'过,所以也许可以帮助更换' ** 0.5'?尽管这可能意味着嵌套两个“评估”电话。 – Divakar
'sqrt'只花了'sum'的大约1%的时间,所以我认为这是一点不必要的优化。 –
谢谢。这比我预期的还要好! – MonkeyButter
@MonkeyButter很高兴帮助! 'np.einsum'是纯粹的魔法! :) – Divakar