我需要计算2D空间中一组点的空间三点相关函数P(r1,r2)。现在我只需要遍历所有三点的点并计算三元组内点对之间的距离r1和r2,然后绘制2D直方图,这给出了我想要的三点相关性。然而,即使对于中等数量的点,这也需要花费很多时间。
问题是是否有可能加快计算速度?
r1 = []
r2 = []
points = [[numpy.random.random(1), numpy.random.random(1)] for i in range(100)]
for x in points:
for y in points:
for z in points:
r1.append(scipy.spatial.distance.euclidean(x, y))
r2.append(scipy.spatial.distance.euclidean(x, z))
pylab.figure()
n, xedges, yedges = numpy.histogram2d(r1, r2, bins = 10)
pylab.imshow(n, interpolation='nearest', origin='low',
extent=[xedges[0], xedges[-1], yedges[0], yedges[-1]])
答案 0 :(得分:4)
for x in points:
for y in points:
r1.append(scipy.spatial.distance.euclidean(x, y))
for z in points:
r2.append(scipy.spatial.distance.euclidean(x, z))
将复杂性从立方减少到二次。我不能提出更多建议,因为我不知道问题所在。
答案 1 :(得分:3)
一些可以加快速度的事情:
首先,使用您的点数组,而不是长度为1的ndarrays的嵌套数组,您只需创建一个Nx2
ndarray:
points = np.random.random((N, 2))
接下来,您最终会多次计算每个成对距离,您应该计算每个距离一次,然后循环遍历数组的元素。 Scipy可以使用scipy.spatial.distance.pdist
为您进行此计算。要恢复成对距离矩阵,您必须使用scipy.spatial.distance.squareform
。明确地循环遍历矩阵的元素:
r1 = []
r2 = []
d = squareform(pdist(points))
for i in range(N):
for j in range(N):
for k in range(N):
r1.append(d[i,j])
r2.append(d[i,k])
最后,您可以通过注意成对距离矩阵d
与输出r1
和r2
之间的关系来使其更简单(您可以通过检查一些小的{{ {1}},如3)。使用某些数组操作,您可以使用以下命令恢复相同的数组:
N
在慢速计算机上仅使用中等d = squareform(pdist(points))
r1 = np.tile(d.reshape((N**2, 1)), N).flatten()
r2 = np.tile(d, N).flatten()
,而代码在1.15秒运行时,显式循环的方法需要12.7 ms,而数组操作快捷方式需要362μs,后两种应该缩放比原始代码更好。