我编写了克里金算法,但我发现它很慢。特别是,你对如何在下面的cons函数中矢量化代码片段有所了解吗?
import time
import numpy as np
B = np.zeros((200, 6))
P = np.zeros((len(B), len(B)))
def cons():
time1=time.time()
for i in range(len(B)):
for j in range(len(B)):
P[i,j] = corr(B[i], B[j])
time2=time.time()
return time2-time1
def corr(x,x_i):
return np.exp(-np.sum(np.abs(np.array(x) - np.array(x_i))))
time_av = 0.
for i in range(30):
time_av+=cons()
print "Average=", time_av/100.
编辑:奖金问题
corr(B[i], C[j])
如果我的p-norm命令是一个数组,scipy解决方案会发生什么:
p=np.array([1.,2.,1.,2.,1.,2.])
def corr(x, x_i):
return np.exp(-np.sum(np.abs(np.array(x) - np.array(x_i))**p))
对于2.,我尝试了P = np.exp(-cdist(B, C,'minkowski', p))
但是scipy期待一个标量。
答案 0 :(得分:4)
你的问题看起来很简单。对于要计算的每对B
行
P[i,j] = np.exp(-np.sum(np.abs(B[i,:] - B[j,:])))
你可以利用数组广播并引入第三个维度,总结最后一个:
P2 = np.exp(-np.sum(np.abs(B[:,None,:] - B),axis=-1))
我们的想法是重塑第一次出现B
以塑造(N,1,M)
,而第二B
留下形状(N,M)
。对于阵列广播,后者相当于(1,N,M)
,所以
B[:,None,:] - B
的形状为(N,N,M)
。然后,沿着最后一个索引求和将得到您正在寻找的(N,N)
- 形状相关数组。
请注意,如果您使用scipy
,则可以使用scipy.spatial.distance.cdist
(或等效地,scipy.spatial.distance.pdist
和scipy.spatial.distance.squareform
的组合)执行此操作,不必要地计算该对称矩阵的下三角半部分。在评论中使用@Divakar的建议以最简单的方式:
from scipy.spatial.distance import cdist
P3 = 1/np.exp(cdist(B, B, 'minkowski',1))
cdist
将计算1-norm中的Minkowski距离,这正是坐标差的绝对值之和。