这里是一个Cython实现,在我的电脑上,该示例的速度提高了3倍以上。对于更大的数组,应该重新评估这个计时,因为BLAS例程可能比这个相当天真的代码更好地扩展。
我知道你要求一些在scipy/numpy/scikit-learn内部的东西,但也许这会为你打开新的可能性:
文件my_cython.pyx
:
import numpy as np
cimport numpy as np
import cython
cdef extern from "math.h":
double abs(double t)
@cython.wraparound(False)
@cython.boundscheck(False)
def pairwise_distance(np.ndarray[np.double_t, ndim=1] r):
cdef int i, j, c, size
cdef np.ndarray[np.double_t, ndim=1] ans
size = sum(range(1, r.shape[0]+1))
ans = np.empty(size, dtype=r.dtype)
c = -1
for i in range(r.shape[0]):
for j in range(i, r.shape[0]):
c += 1
ans[c] = abs(r[i] - r[j])
return ans
答案是一个包含所有非重复评估的一维数组。
要导入到Python中:
import numpy as np
import random
import pyximport; pyximport.install()
from my_cython import pairwise_distance
r = np.array([random.randrange(1, 1000) for _ in range(0, 1000)], dtype=float)
def solOP(r):
return np.abs(r - r[:, None])
使用IPython进行时间控制:
In [2]: timeit solOP(r)
100 loops, best of 3: 7.38 ms per loop
In [3]: timeit pairwise_distance(r)
1000 loops, best of 3: 1.77 ms per loop
scipy.spatial.distance.pdist
。我不确定这是否是最快的选项,因为它需要检查多维数据、非欧几里德范数和其他东西,但它是内置的。 - user2357112numpy
使用了 BLAS 或 MKL 编译,直接从 sourceforge 下载的可能没有使用这些编译选项。 - CT Zhuscipy
总是使用 BLAS 编译的,这不像numpy
那样是可选的。 - askewchan