【问题标题】:How to calculate distances in 3D coordinates in an array如何计算数组中 3D 坐标中的距离
【发布时间】:2019-06-20 00:18:30
【问题描述】:

我正在尝试计算点之间的初始距离和后续距离。 我得到的数据是一个 csv,其中每三列对应一个 LED 标记。即第 1 列是标记 1 的 x 坐标,第 2 列是标记 1 的 y 坐标,第 3 列是标记 1 ets 的 z 坐标。每行对应于记录该位置的时间。 我很难找出组织数据的最佳方式,以便我可以使用它。 我需要 a) 在时间 0 找到标记之间的初始位置和初始距离 b) 找出不同时间标记之间距离的任何变化。

我最初将所有 x 坐标放在一个数组中,将所有 y 坐标放在一个数组中,将所有 z 坐标放在一个数组中,但意识到我不能(不知道如何?)迭代数组所以我可以找到相邻点之间的差异。 IE。标记 1 和标记 2 之间的距离是 sqrt((x2-x1)**2+(y2-y1)**2+(z2-z1)**2) 但由于 x2 和 x1 在同一个数组中,所以不能t (不知道怎么做?)迭代所有 xs (分别是 ys 和 zs )之间的差异。 在下面的代码中,我转置了数组,以便可以遍历行(而不是列)

for i in range(m): #where m is the number of markers
    x_diff= x_array[i+1]-x_array[i]
    y_diff=y_array[i+1]-y_array[i]
    z_diff=z_array[i+1]-z_array[i]
    dist=np.sqrt(x_diff**2+y_diff**2+z_diff**2)

我想要一个数组,其中每列是相邻标记之间的欧几里得距离,行对应于每次的距离。

【问题讨论】:

  • 您的方法似乎很好:对于每个第 i 个元素,计算到下一个 (i+1th) 元素的距离。由于 i+1,当您到达最后一个元素时,您可能会访问数组末尾之后的 1,因此请确保 m 说明了这一点。您能否进一步解释您所描述的方法存在哪些问题?
  • 所以我确实使用了 m-1 的范围来解释这一点。我遇到的问题是 x、y 和 z 坐标的每个数组的形状是 (23369,250),而结果数组 dist 的形状是 (23369,),即假设所有时间都被计算在内,但两点之间只有距离,而不是所有相邻点之间的距离。生成的数组应具有形状 (23369, 249)。
  • 此行为表明 dist 不会为每次迭代存储,而是被最近迭代的结果覆盖。您是否尝试在 for 循环之外声明 dist = [],然后在每次迭代时执行 dist.append(np.sqrt(...)) 之类的操作,而不是 dist=
  • 这成功了。谢谢!

标签: python numpy


【解决方案1】:

您可以将 SciPy 的 pdist 函数用于成对距离。例如,

>>> X
array([[1, 2, 3],
       [1, 2, 3],
       [4, 0, 0]])
>>> from scipy.spatial.distance import pdist
>>> pdist(X)
array([0.        , 4.69041576, 4.69041576])

距离成对输出 (0,1), (0,2), (1,2)。

【讨论】:

    【解决方案2】:

    这里是从一个像原始 csv 一样布局的数组开始的分步操作:

    # 2 time points, 4 markers, values between 0 and 8
    csv = np.random.randint(0,9,(2,12))
    csv
    # array([[8, 5, 3, 2, 3, 2, 2, 5, 6, 8, 2, 4],
    #        [8, 2, 7, 4, 7, 7, 8, 0, 3, 0, 2, 4]])
    
    # reshape to get x,y,z aligned
    m,n = csv.shape
    xyz = csv.reshape(m,-1,3)
    xyz
    # array([[[8, 5, 3],
    #         [2, 3, 2],
    #         [2, 5, 6],
    #         [8, 2, 4]],
    #
    #        [[8, 2, 7],
    #         [4, 7, 7],
    #         [8, 0, 3],
    #         [0, 2, 4]]])
    
    # get coordinate-wise differences between adjacent markers
    dist_1d = np.diff(xyz,axis=1)
    dist_1d
    # array([[[-6, -2, -1],
    #         [ 0,  2,  4],
    #         [ 6, -3, -2]],
    #
    #        [[-4,  5,  0],
    #         [ 4, -7, -4],
    #         [-8,  2,  1]]])
    
    # compute squared Euclidean distance
    # (you could take the square root of that but if you are
    # only interested in changes it doesn't seem necessary)
    eucl2 = (dist_1d*dist_1d).sum(axis=2)
    eucl2
    # array([[41, 20, 49],
    #        [41, 81, 69]])
    

    【讨论】:

      【解决方案3】:

      您需要将该 2d 数组转换为 3d 数组。

      rows, cols = csv.shape
      csv_3d = csv.reshape(rows, -1, 3)
      

      然后np.diff沿第二个轴(点之间)

      del_csv_3d = np.diff(csv_3d, axis = 1)
      

      然后沿最后一个轴取范数

      out = np.linalg.norm(del_csv_3d , axis = -1)
      

      这应该是您需要的数据。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-11-12
        • 2017-11-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多