numpy.asarray

时间:2018-12-25 19:02:51

标签: python numpy scipy slice distance

我正在尝试使用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函数为较大的数组提供了内存错误。

1 个答案:

答案 0 :(得分:0)

您的AsBs的长度均为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)存储在内存中也可能会耗尽内存,因此您可能希望随行保存每个块,而不是尝试一次重建整个对象。