【问题标题】:Distance between 2 points in 3D for a big array大阵列的 3D 中 2 点之间的距离
【发布时间】:2017-01-18 15:26:57
【问题描述】:

我有一个数组n×m,其中n = 217000m = 3(一些来自望远镜的数据)。

我需要计算 3D 中 2 个点之间的距离(根据我的 x、y、z 列中的坐标)。

当我尝试使用sklearn 工具时,结果是:

ValueError: array is too big; `arr.size * arr.dtype.itemsize` is larger than the maximum possible size.

在这种情况下我可以使用什么工具以及该工具的最大可能尺寸是多少?

【问题讨论】:

  • 您需要计算只有2个点(即点nr 5和点nr 214987)之间的距离还是所有点之间的距离(即点nr 1 和点 nr 2,然后点 nr 1 和点 nr 3,......)?
  • 数组和项目大小是多少?

标签: python numpy scikit-learn distance


【解决方案1】:

在这种情况下我可以使用什么工具...?

您可以使用@Saksow 建议的方法自行实现欧几里得距离函数。假设ab是一维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 了解更多详细信息)。

【讨论】:

    【解决方案2】:

    仅使用 Python 和 Euclidean distance 3 维公式:

    import math
    distance = math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2 + (z1 - z2) ** 2)
    

    【讨论】:

    • 我猜你的意思是** 2
    • 哦,是的,抱歉,这完全不同,谢谢
    • 绝对如此,我会去的。没有必要使工具复杂化。你打败了我的答案。 :D
    猜你喜欢
    • 1970-01-01
    • 2021-08-06
    • 2019-03-28
    • 2015-08-16
    • 2021-03-03
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多