(稀疏)numpy.meshgrid

时间:2019-01-15 16:32:35

标签: python numpy scipy-spatial

我想计算常规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()与稀疏的网格网格结合在一起。

2 个答案:

答案 0 :(得分:1)

我不确定使用稀疏网状网格会为您带来什么。您可以节省网格网格本身的空间,但是仍然需要计算相同数量的成对距离,并且根据pdist上的文档,最终结果仍将是“压缩”矩阵。

如果您尝试优化将要执行的距离计算的数量,则网格立即有规律地间隔的事实会立即提示一些优化。

这是一种算法:

  1. 遍历所有坐标对

  2. 创建一个“距离缓存”,该距离缓存将坐标对之间的差异用作键。例如,distance_cache [(3,4)] =5。这样,如果找到彼此相对距离相同的两个坐标,则只需从高速缓存中查找坐标之间的距离,而无需重新计算。

  3. 加分点:仅将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进行隐式重复。