繁体   English   中英

scipy和numpy中的快速距离计算

[英]Fast distance calculation in scipy and numpy

A,B((day,observation,dim))数组。 每个数组在给定的一天包含相同数量的观察值,观察值是具有暗淡维度的点(即暗淡的浮点数)。 对于每一天,我想计算当天AB中所有观测值之间的空间距离。

例如:

import numpy as np
from scipy.spatial.distance import cdist

A, B = np.random.rand(50,1000,10), np.random.rand(50,1000,10)

output = []
for day in range(50):
    output.append(cdist(A[day],B[day]))

我在哪里使用scipy.spatial.distance.cdist

有更快的方法吗? 理想情况下,我想获得output a ((day,observation,observation))数组,该数组每天包含AB中观察值之间的成对距离,同时以某种方式避免循环数天。

一种方法(虽然它需要大量的内存)是巧妙地使用阵列广播:

output = np.sqrt( np.sum( (A[:,:,np.newaxis,:] - B[:,np.newaxis,:,:])**2, axis=-1) )

编辑

但经过一些测试,似乎scikit-learn的euclidean_distances可能是大型阵列的最佳选择。 (请注意,我已将循环重写为列表解析。)

这是每天100个数据点:

# your own code using cdist
from scipy.spatial.distance import cdist
%timeit dists1 = np.asarray([cdist(x,y) for x, y in zip(A, B)])

100 loops, best of 3: 8.81 ms per loop

# pure numpy with broadcasting
%timeit dists2 = np.sqrt( np.sum( (A[:,:,np.newaxis,:] - B[:,np.newaxis,:,:])**2, axis=-1) )

10 loops, best of 3: 46.9 ms per loop

# scikit-learn's algorithm
from sklearn.metrics.pairwise import euclidean_distances
%timeit dists3 = np.asarray([euclidean_distances(x,y) for x, y in zip(A, B)])
100 loops, best of 3: 12.6 ms per loop

这是每天2000个数据点:

In [5]: %timeit dists1 = np.asarray([cdist(x,y) for x, y in zip(A, B)])
1 loops, best of 3: 3.07 s per loop

In [7]: %timeit dists3 = np.asarray([euclidean_distances(x,y) for x, y in zip(A, B)])

1 loops, best of 3: 2.94 s per loop

编辑:我是个白痴,忘记了python的map是懒洋洋地评估的。 我的“更快”的代码实际上并没有做任何工作! 强制评估消除了性能提升。

我认为你的时间将由scipy函数内部所花费的时间占据主导地位。 我总是使用map而不是循环,因为我认为它有点整洁,但我不认为有任何神奇的方法可以在这里获得巨大的性能提升。 也许使用cython或使用numba编译代码会有所帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM