让<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form>
<div class="group">
<div class="choice">
<input type="radio" name="group[0][]" value="admin" />
<label>Admin</label>
</div>
<div class="choice">
<input type="radio" name="group[0][]" value="user" />
<label>User</label>
</div>
<div class="choice">
<input type="radio" name="group[0][]" value="moderator" />
<label>Moderator</label>
</div>
</div>
<div class="group">
<div class="choice">
<input type="radio" name="group[1][]" value="admin" />
<label>Admin</label>
</div>
<div class="choice">
<input type="radio" name="group[1][]" value="user" />
<label>User</label>
</div>
<div class="choice">
<input type="radio" name="group[1][]" value="moderator" />
<label>Moderator</label>
</div>
</div>
</form>
为A,B
个数组。每个数组在给定的一天包含相同数量的观察值,观察值是具有暗淡维度的点(即暗淡的浮点数)。对于每一天,我想计算当天((day,observation,dim))
和A
中所有观测值之间的空间距离。
例如:
B
我使用scipy.spatial.distance.cdist
。
有更快的方法吗?理想情况下,我希望获得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]))
一个output
数组,该数组每天包含((day,observation,observation))
和A
中观察值之间的成对距离,同时以某种方式避免循环过了几天。
答案 0 :(得分:4)
一种方法(尽管需要大量内存)是巧妙地使用阵列广播:
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
答案 1 :(得分:2)
编辑:我是个白痴,忘记了python的map
被懒惰地评估了。我的“更快”的代码实际上并没有做任何工作!强制评估消除了性能提升。
我认为你的时间将由scipy函数内部所花费的时间占主导地位。我总是使用map
而不是循环,因为我认为它有点整洁,但我不认为有任何神奇的方法可以在这里获得巨大的性能提升。也许使用cython或使用numba编译代码会有所帮助。