在这种情况下我可以使用什么工具...?
您可以使用@Saksow 建议的方法自行实现欧几里得距离函数。假设a和b是一维NumPy数组,你也可以使用this thread中提出的任何方法:
import numpy as np
np.linalg.norm(a-b)
np.sqrt(np.sum((a-b)**2))
np.sqrt(np.dot(a-b, a-b))
如果您希望一次性计算您的 数组中所有点之间的成对距离(不一定是欧几里得 距离),那么模块scipy.spatial.distance 就是您的朋友。
演示:
In [79]: from scipy.spatial.distance import squareform, pdist
In [80]: arr = np.asarray([[0, 0, 0],
...: [1, 0, 0],
...: [0, 2, 0],
...: [0, 0, 3]], dtype='float')
...:
In [81]: squareform(pdist(arr, 'euclidean'))
Out[81]:
array([[ 0. , 1. , 2. , 3. ],
[ 1. , 0. , 2.23606798, 3.16227766],
[ 2. , 2.23606798, 0. , 3.60555128],
[ 3. , 3.16227766, 3.60555128, 0. ]])
In [82]: squareform(pdist(arr, 'cityblock'))
Out[82]:
array([[ 0., 1., 2., 3.],
[ 1., 0., 3., 4.],
[ 2., 3., 0., 5.],
[ 3., 4., 5., 0.]])
请注意,此玩具示例中使用的模拟数据数组中的点数为 ,生成的成对距离数组包含 元素。
...这个工具的最大可能尺寸是多少?
如果您尝试使用您的数据 () 应用上述方法,则会收到错误:
In [105]: data = np.random.random(size=(217000, 3))
In [106]: squareform(pdist(data, 'euclidean'))
Traceback (most recent call last):
File "<ipython-input-106-fd273331a6fe>", line 1, in <module>
squareform(pdist(data, 'euclidean'))
File "C:\Users\CPU 2353\Anaconda2\lib\site-packages\scipy\spatial\distance.py", line 1220, in pdist
dm = np.zeros((m * (m - 1)) // 2, dtype=np.double)
MemoryError
问题是您的内存不足。要执行这样的计算,您需要超过 350TB!所需的内存量是距离矩阵的元素数 (2170002) 乘以该矩阵的每个元素的字节数 (8),然后将该乘积除以适当的因子(10243) 以千兆字节表示结果:
In [107]: round(data.shape[0]**2 * data.dtype.itemsize / 1024.**3)
Out[107]: 350.8
因此,数据的最大允许大小取决于可用 RAM 的数量(请查看 this thread 了解更多详细信息)。