【问题标题】:Calculate sum of distances travelled for each unique ID计算每个唯一 ID 的行进距离总和
【发布时间】:2021-09-30 00:40:54
【问题描述】:

我有一个包含三列的数据框。一列包含 x 坐标,另一列包含 y 坐标。此外,如您所见,还有一个“trackid”列——该列将所有 x 和 y 坐标与特定的唯一 trackid 相关联。

    trackiD   X_COORDINATES     Y_COORDINATES
        
     2        542.299805        23.388090
     2        544.108215        23.575758
     2        545.300598        23.962421
     2        546.417053        25.049328
     2        546.198669        24.830357
     2        546.724915        24.916084
     2        547.037048        24.918982
     2        547.011963        24.785202
     2        547.649231        24.845772
     3        547.600525        24.613401
     3        547.891479        24.268734
     3        548.580505        24.459103
     3        548.144409        23.915531
     3        548.626770        23.922005
     4        548.527222        24.134670
     4        548.504211        23.642254
     4        548.936584        24.028818
     4        548.627869        23.295454

我想要做的是:

  • 获取每对 x 和 y 坐标,并使用毕达哥拉斯距离公式计算它们之间的距离增量: (sqrt(x2-x1)^2 + (y2-y1)^2),将每个距离增量添加到列表中,然后取列表中所有增量的总和以获得总行驶距离——同样需要注意的是,我只对唯一 trackid 中的每组坐标进行此计算。 IE。计算 trackid 2 的距离增量总和,然后分别对 trackid 3 和 4 执行相同的过程,依此类推 - 最终将每个唯一轨道 ID 的所有总行驶距离存储在一个新列表中。

这是我当前的代码——它可以运行,但问题是,它输出一个列表,其中只有一个大的、可能不正确的值(如下所示) . 'value'变量似乎已被切断并在stackoverflow上跨多行显示,但当我在jupyter笔记本中运行它时并非如此。

       def pythag_dis(U_id):
          c = data.Unique_id == U_id
          df = data[c]
          df.reset_index(inplace = True)
          k = sorted(df.trackId.unique())
          i = 0
          j = 1
          length = len(k)
          while i < length: 
            condition = df.trackId == k[i]
            df2 = df[condition]
            df2.reset_index(inplace = True)
            value = 
           math.sqrt((df.Object_Center_0.iloc[j] - 
           df.Object_Center_0.iloc[i])**2 + 
           (df.Object_Center_1.iloc[j] - 
           df.Object_Center_1.iloc[i])**2)
           mylist = []
           mylist.append(value)
           fulldistance = sum(mylist)
           mylist2 = []
           mylist2.append(fulldistance)
           i+=1
      return mylist2
    pythag_dis('1CCM0701')

OUTPUT: [1976.075585650214]

【问题讨论】:

  • 您显示的代码无法运行,因为它有错误的缩进。
  • 你打算用mylist2 = []这一行来实现什么?
  • @mkrieger1 对此感到抱歉 - 只是试图修复它。当我粘贴到 stackoverflow 时,格式被丢弃了。
  • @mkrieger1 所以对于 mylist 我必须存储所有距离增量值,然后将所有这些值相加以计算总距离。然后想法是将总距离值存储在一个新列表中——mylist2
  • @mkrieger1 啊——我在考虑回答这个问题时发现我的代码中有错误。我实际上不希望每次代码循环时都创建一个列表,每个列表应该只存在一次,因此我应该在循环之外定义空列表。

标签: python pandas list loops


【解决方案1】:

使用 Pandas 的可能解决方案:我使用 pandas groupby shift 来匹配坐标,计算距离,然后对组中的距离求和:

import math
import numpy as np
import pandas as pd

def distance(row):
    x1, y1, x2, y2 = row["X_COORDINATES"], row["Y_COORDINATES"], row["X2"], row["Y2"]
    if np.isnan(x2) or np.isnan(y2):
        return 0
    return math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)

df["X2"] = df.groupby("trackiD")["X_COORDINATES"].shift(-1)
df["Y2"] = df.groupby("trackiD")["Y_COORDINATES"].shift(-1)

df["distance"] = df.apply(distance, axis=1)
df.groupby("trackiD")["distance"].sum()

输出:

trackiD
2    6.560621
3    2.345185
4    1.868628
Name: distance, dtype: float64

测试数据框:

df = pd.DataFrame(
    {
        "trackiD": {
            0: 2,
            1: 2,
            2: 2,
            3: 2,
            4: 2,
            5: 2,
            6: 2,
            7: 2,
            8: 2,
            9: 3,
            10: 3,
            11: 3,
            12: 3,
            13: 3,
            14: 4,
            15: 4,
            16: 4,
            17: 4,
        },
        "X_COORDINATES": {
            0: 542.299805,
            1: 544.108215,
            2: 545.300598,
            3: 546.417053,
            4: 546.198669,
            5: 546.724915,
            6: 547.037048,
            7: 547.011963,
            8: 547.649231,
            9: 547.600525,
            10: 547.891479,
            11: 548.580505,
            12: 548.144409,
            13: 548.62677,
            14: 548.527222,
            15: 548.504211,
            16: 548.936584,
            17: 548.627869,
        },
        "Y_COORDINATES": {
            0: 23.38809,
            1: 23.575758,
            2: 23.962421,
            3: 25.049328,
            4: 24.830357,
            5: 24.916084,
            6: 24.918982,
            7: 24.785202,
            8: 24.845772,
            9: 24.613401,
            10: 24.268734,
            11: 24.459103,
            12: 23.915531,
            13: 23.922005,
            14: 24.13467,
            15: 23.642254,
            16: 24.028818,
            17: 23.295454,
        },
    }
)

【讨论】:

  • 谢谢,这个方法效果很好!在使用这种方法时,如果行进距离的跳跃太大,是否有一种简单的方法可以过滤掉一整套trackiD?我认为在我的初始跟踪中可能存在问题,并且想要删除在给定增量内行进 75 个单位或更多距离的任何 trackiD - 总行进距离 > 75 很好,但在坐标之间太大。跨度>
  • 最后一个 groupby 结果是 pandas 系列。您可以轻松过滤。
【解决方案2】:

首先创建两个新列,X_SHIFTEDY_SHIFTED,表示每个轨道 ID 的下一个点的坐标。我们通过结合df.groupbydf.shift 来做到这一点:

df[['X_SHIFTED', 'Y_SHIFTED']] = df.groupby('trackiD').shift()

然后,只需使用点之间的欧几里得距离公式(X_COORDINATESY_COORDINATES)和(X_SHIFTEDY_SHIFTED)。我们可以使用df.apply row-wise (axis=1) 和math.dist 来做到这一点:

import math

df['DIST'] = df.apply(
    lambda row: math.dist(
        (row['X_COORDINATES'], row['Y_COORDINATES']),
        (row['X_SHIFTED'], row['Y_SHIFTED'])
    ), axis=1)

输出:

    trackiD  X_COORDINATES  Y_COORDINATES   X_SHIFTED  Y_SHIFTED      DIST
0         2     542.299805      23.388090         NaN        NaN       NaN
1         2     544.108215      23.575758  542.299805  23.388090  1.818122
2         2     545.300598      23.962421  544.108215  23.575758  1.253509
3         2     546.417053      25.049328  545.300598  23.962421  1.558152
4         2     546.198669      24.830357  546.417053  25.049328  0.309257
5         2     546.724915      24.916084  546.198669  24.830357  0.533183
6         2     547.037048      24.918982  546.724915  24.916084  0.312146
7         2     547.011963      24.785202  547.037048  24.918982  0.136112
8         2     547.649231      24.845772  547.011963  24.785202  0.640140
9         3     547.600525      24.613401         NaN        NaN       NaN
10        3     547.891479      24.268734  547.600525  24.613401  0.451054
11        3     548.580505      24.459103  547.891479  24.268734  0.714841
12        3     548.144409      23.915531  548.580505  24.459103  0.696886
13        3     548.626770      23.922005  548.144409  23.915531  0.482404
14        4     548.527222      24.134670         NaN        NaN       NaN
15        4     548.504211      23.642254  548.527222  24.134670  0.492953
16        4     548.936584      24.028818  548.504211  23.642254  0.579981
17        4     548.627869      23.295454  548.936584  24.028818  0.795693

要获得每个轨道的距离总和,您可以使用:

df.groupby('trackiD')['DIST'].sum()

输出:

trackiD
2    6.560621
3    2.345185
4    1.868628
Name: DIST, dtype: float64

【讨论】:

  • 所以在运行第一段代码时,我不断收到错误消息,指出列的长度必须与键的长度相同——我认为这是由于 NaN 值。有没有办法让它只插入 NaN?
  • 不确定问题出在哪里 - 我只用您在 OP 中提供的数据框进行了测试。我也不认为它与 NaN 值有关。您是否使用确切的示例输入运行了我发布的确切代码?
  • 是的,当我使用确切的样本数据和完整的数据集运行它时,它实际上给出了相同的错误
猜你喜欢
  • 2019-05-10
  • 1970-01-01
  • 2020-10-13
  • 2015-05-11
  • 1970-01-01
  • 2018-06-28
  • 1970-01-01
  • 1970-01-01
  • 2016-12-24
相关资源
最近更新 更多