我正在尝试使用scipy.distance.cdist计算空间中点的距离。 A包含Na个点的位置,B包含Nb个点的位置。
import numpy as np
from scipy.spatial import distanceNa=100
Na=100
Nb=500
A=np.random.rand(Na,3)
B=np.random.rand(Nb,3)
dist=distance.cdist(A,B)
将给我A和B中的点之间的距离。但是,当Na> 20000且Nb> 500 000时,此函数将产生内存错误。为了克服这个问题,我试图将A和B切成较小的块,计算距离并将它们连接起来:
import numpy as np
from scipy.spatial import distanceNa=100
Na=100
Nb=500
A=np.random.rand(Na,3)
B=np.random.rand(Nb,3)
As=np.array_split(A,10)
Bs=np.array_split(B,10)
np.asarray([distance.cdist(X,Y) for X in As for Y in Bs]).shape
这将返回(100,10,50)。我了解第一个维度,但是为什么是10和50? 更有趣的是,如果我更改Na = 102,则这次它将返回:(100,)。 在这种情况下,我的代码:
QQ=np.asarray([distance.cdist(X,Y) for X in As for Y in Bs])
QQ.reshape(len(As),len(Bs)
JJ=[np.concatenate((QQ[i,:]),axis=1) for i in range(len(As))]
dist=np.concatenate((JJ[:]),axis=0)
给出与distance.cdist(A,B)完全相同的矩阵。但是,如果Na = 100,则先前数组的Nb = 500形状将是(100,10,50),可以防止重塑和连接操作。 有没有更好的pythonic方法来做到这一点?基本上我的问题是cdist函数为较大的数组提供了内存错误。
答案 0 :(得分:0)
您的As
和Bs
的长度均为10,因此您的Z = [distance.cdist(X,Y) for X in As for Y in Bs]
的长度为100。
此列表中的每个条目都是一个10,50形状的numpy数组,因为每个X
的长度为Na/10 = 10
,每个Y
的长度为Nb/10 = 50
。>
调用as_array
时会得到一个大小为(100,10,50)
的numpy数组,因为列表Z
刚好成为该数组的轴0。
请注意,Z
的第一个条目与As
的第一个块对应于Bs
的第一个块。 Z
的第二个条目对应于As
的第一个块和Bs
的第二个块。通常,k
的第Z
个条目对应于Z%len(As)
的{{1}}块和As
的{{1}}块。
但是,将所有A//len(As)
存储在内存中也可能会耗尽内存,因此您可能希望随行保存每个块,而不是尝试一次重建整个对象。