Vectorise Python代码

时间:2016-10-10 10:35:21

标签: python numpy vectorization

我编写了克里金算法,但我发现它很慢。特别是,你对如何在下面的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.

编辑:奖金问题

  1. 如果我想{C}与C相同的尺寸corr(B[i], C[j])
  2. ,广播解决​​方案会发生什么
  3. 如果我的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期待一个标量。

1 个答案:

答案 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.pdistscipy.spatial.distance.squareform的组合)执行此操作,不必要地计算该对称矩阵的下三角半部分。在评论中使用@Divakar的建议以最简单的方式:

from scipy.spatial.distance import cdist
P3 = 1/np.exp(cdist(B, B, 'minkowski',1))

cdist将计算1-norm中的Minkowski距离,这正是坐标差的绝对值之和。