我有一个向量a
,需要对两个索引进行求和,例如
for i in (range, n):
for j in (i+1, n):
F(a[i] - a[j])
F
函数在哪里:求和是在对数组的上三角求和。
我以numpy的最快方式阅读了有趣的线程,以对内存最少的上三角元素求和,并进行了试验:确实,ARRAY.sum是对上三角矩阵的元素求和的非常快速的方法。
要将方法应用于我的情况,我首先需要定义一个数组,例如
A[i,j] = F(a[i],a[j])
然后计算
(A.sum() - np.diag(A).sum())/2
我当然可以A
通过两个for循环来定义数组,但是我想知道是否有更快,更麻木的方法。
在另一种情况下,该函数F
等于
F = a[i]*a[j]
我可以写
def sum_upper_triangular(vector):
A = np.tensordot(vector,vector,0)
return (A.sum() - np.diag(A).sum())/2
这比直接与sum()
或嵌套循环要快得多。
F
例如,如果更明确
np.exp(a[i] - a[j])
我想知道最有效的方法。
非常感谢
您可以使用scipy.spatial.pdist
度量标准并为其设置任何功能。另外,pdist
仅计算非对角三角形,因此您无需将其从sum
from scipy.spatial.distance import pdist
def sum_upper_tri(arr, F = lambda x, y: x*y):
return pdist(arr.reshape(arr.shape[0], -1), metric = F).sum()/2
但是,如果您想要一些超级快的东西,您将需要numba
:
from numba import jit
@jit
def sum_upper_tri_jit(arr, F = lambda x, y: x * y):
out = 0
for i in range(1, len(arr)):
for j in range(i + 1, len(arr)):
out += F(arr[i], arr[j])
return out / 2
还没有找到解决方法@njit
,但是如果可以的话,它会更快。
在任何情况下,每一个预期的特制功能F
都会更快。例如,exp(|x-y|)
大小写(exp(x-y)
不对称的提示:xy!= yx)
from numba import njit
@njit
def sum_upper_tri_exp(arr):
out = 0
for i in range(1, len(arr)):
for j in range(i + 1, len(arr)):
out += np.exp(np.abs(arr[i] - arr[j]))
return out / 2
这比上述速度快约100倍
如果您不想求和,可以使用:
from numba import njit
@njit
def sum_upper_tri_exp(arr):
out = []
for i in range(1, len(arr)):
for j in range(i + 1, len(arr)):
out += [np.exp(arr[i] - arr[j])]
return out
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句