我想计算常规3D网格上每对节点之间的距离。网格可能很大,所以我想优化计算(特权给CPU)。
经过许多测试,我放弃了仅适用于python2的“ scitools”模块,并结合使用numpy.meshgrid()和scipy.spatial.distance.pdist()。例如,对于20x20x20的网格:
distances = scipy.spatial.distance.pdist(np.transpose(np.array(np.meshgrid(range(-10,10,1),range(-10,10,1),range(-10,10,1)))).reshape([20**3,3]))
是否已优化?
第一个“也许这就是要走的路...”:我看到meshgrid中有一个“稀疏”选项,所以请我使用
np.meshgrid(range(-10,10,1),range(-10,10,1),range(-10,10,1),sparse=True)
而不是
np.meshgrid(range(-10,10,1),range(-10,10,1),range(-10,10,1))
实际上,我什至可以将稀疏形状保留在内存中,因为稍后在代码中会很方便。但是我找不到令人满意的语法将pdist()与稀疏的网格网格结合在一起。
答案 0 :(得分:1)
我不确定使用稀疏网状网格会为您带来什么。您可以节省网格网格本身的空间,但是仍然需要计算相同数量的成对距离,并且根据pdist上的文档,最终结果仍将是“压缩”矩阵。
如果您尝试优化将要执行的距离计算的数量,则网格立即有规律地间隔的事实会立即提示一些优化。
这是一种算法:
遍历所有坐标对
创建一个“距离缓存”,该距离缓存将坐标对之间的差异用作键。例如,distance_cache [(3,4)] =5。这样,如果找到彼此相对距离相同的两个坐标,则只需从高速缓存中查找坐标之间的距离,而无需重新计算。
加分点:仅将x和y相对质数存储在距离缓存中的键。由于三角形的相似性,可以将相同的缓存条目重复用于键的倍数。例如,distance([6,8],[0,0])= 2 * d [(3,4)] = 10
答案 1 :(得分:0)
In [494]: [x.shape for x in np.meshgrid(range(-10,10,1),range(-10,10,1),range(-1
...: 0,10,1),sparse=False)]
Out[494]: [(20, 20, 20), (20, 20, 20), (20, 20, 20)]
In [495]: [x.shape for x in np.meshgrid(range(-10,10,1),range(-10,10,1),range(-1
...: 0,10,1),sparse=True)]
Out[495]: [(1, 20, 1), (20, 1, 1), (1, 1, 20)]
非稀疏的网格生成3个3d数组,您可以将其合并并整形为3列数组。稀疏版本还生成3d数组,但是每个数组的形状都不同。使用broadcasting
可以以相同的方式使用它们。例如,如果相加或相乘,则两种情况下的结果都是(20,20,20)数组。但是,如果不扩展,稀疏数组就不能做成那个(20 * 20 * 20,3)数组。
这些不是scipy sparse
数组。那是一个完全不同的概念。
查看那些(20,20,20)
数组之一。查看所有重复的列或行吗? sparse
只是避免重复这些操作。它只需要20个元素range
并对其进行重塑。它可以让broadcasting
进行隐式重复。