【问题标题】:Calculate distance a dataframe with UTM coordinates in pandas在熊猫中计算具有UTM坐标的数据框的距离
【发布时间】:2019-11-09 05:20:38
【问题描述】:

我有一个巨大的dataframe。结构数据如下所示:

df
ID  Annotation  X           Y
A   Boarding    767513.9918 9425956.2571
A   Alighting   767154.1396 9427584.0004
B   Boarding    767450.5277 9432627.9543
B   Alighting   767495.0101 9426797.1772
C   Boarding    767648.9507 9426442.5497
C   Alighting   767037.0309 9428878.9032
........

X 和 Y 数据使用 UTM 坐标。我想计算每个ID登机和下车之间的距离。我的问题与这个问题(Distance matrix in Python Pandas)非常相似但又不同。我的预期结果如下所示:

result
ID  Anotation_1 X_1         Y_1         Anotation_2 X_2         Y_2      Dist
A   Boarding    767513.99   9425956.26  Alighting   767154.14   9427584.00  1667.05
B   Boarding    767450.53   9432627.95  Alighting   767495.01   9426797.18  5830.95
C   Boarding    767648.95   9426442.55  Alighting   767037.03   9428878.90  2512.02
    .......

感谢您的帮助。

【问题讨论】:

  • 为什么上下车值会互换?
  • @anky_91 我再次编辑了这个问题。谢谢。
  • 距离是一个ID(人)的上下车点两点位置之间的距离。我使用 UTM(宇宙横向墨卡托)坐标系math.stackexchange.com/questions/738529/…

标签: python pandas distance utm


【解决方案1】:

我会旋转数据框:

result = df.pivot('ID', 'Annotation', ['X', 'Y'])

得到

                      X                          Y              
Annotation    Alighting     Boarding     Alighting      Boarding
ID                                                              
A           767154.1396  767513.9918  9.427584e+06  9.425956e+06
B           767495.0101  767450.5277  9.426797e+06  9.432628e+06
C           767037.0309  767648.9507  9.428879e+06  9.426443e+06

然后我会重命名列并重新索引:

ix = result.columns.to_frame()
result.columns = ix['Annotation'] + '_' + ix.iloc[:,0]
result = result.reindex(columns=['Alighting_X', 'Alighting_Y', 'Boarding_X', 'Boarding_Y'])

得到:

    Alighting_X   Alighting_Y   Boarding_X    Boarding_Y
ID                                                      
A   767154.1396  9.427584e+06  767513.9918  9.425956e+06
B   767495.0101  9.426797e+06  767450.5277  9.432628e+06
C   767037.0309  9.428879e+06  767648.9507  9.426443e+06

现在很容易计算距离:

result['Dist'] = np.sqrt((result.Alighting_X - result.Boarding_X)**2 + (result.Alighting_Y - result.Boarding_Y)**2)

最终得到:

    Alighting_X   Boarding_X   Alighting_Y    Boarding_Y         Dist
ID                                                                   
A   767154.1396  767513.9918  9.427584e+06  9.425956e+06  1667.045847
B   767495.0101  767450.5277  9.426797e+06  9.432628e+06  5830.946773
C   767037.0309  767648.9507  9.428879e+06  9.426443e+06  2512.023929

【讨论】:

  • 谢谢,xy上车下xy很聪明。
【解决方案2】:

我正在使用unstack()

m=(df.assign(k=(df.groupby('ID').cumcount()+1).astype(str)).
        set_index(['ID','k']).unstack().sort_values(by='k',axis=1))
m.columns=m.columns.map('_'.join)

m=m.assign(Dist=np.sqrt((m.X_1 - m.X_2)**2 + (m.Y_1 - m.Y_2)**2))
print(m)

【讨论】:

    【解决方案3】:

    解决此问题的一种方法,假设输入干净且正确,将使用groupby

    df = df.groupby('ID').apply(lambda x: pd.Series(x.values[0:2,2:4].flatten()))  # (*)
    df.columns=['X_1','Y_1','X_2','Y_2']
    #df.reset_index()  # Uncomment if you want 'ID' as a column and not an Index
    

    至于您想要的结果中的其他列:Anotation_1Anotation_2 始终保持不变,所以我没有费心将它们包括在内。 Dist 列——好吧,你现在可以计算它,给定新的列,或者你可以改变上面的代码来计算距离,同时遍历上面步骤(*) 中的数字,从而将我们的代码更改为类似:(这里用的是虚拟距离计算,换成你的吧!)

    def my_func(pdf):
        return pd.Series([pdf.values[0,2], pdf.values[0,3], pdf.values[1,2], pdf.values[1,3],
                          np.sqrt((pdf.values[0,2]-pdf.values[1,2])**2+(pdf.values[0,3]-pdf.values[1,3])**2)  # <= your distance calculation goes here...
                         ])
    df = df.groupby('ID').apply(my_func)
    df.columns=['X_1','Y_1','X_2','Y_2','Dist']
    #df.reset_index()  # Uncomment if you want 'ID' as a column and not an Index
    

    更新:如果您坚持包含这些常量列,您可以稍后像这样简单地添加它们:(但你为什么要这样做?尤其是如果它是一个很大的DataFrame...) p>

    df['Annotation_1'] = 'Boarding'
    df['Annotation_2'] = 'Alighting'
    # And if you further insist on a specific ordering of the columns, you can go with:
    df = df[['Annotation_1', 'X_1', 'Y_1', 'Annotation_2', 'X_2', 'Y_2', 'Dist']]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-06
      • 2020-09-15
      • 1970-01-01
      • 1970-01-01
      • 2021-10-11
      • 2018-12-20
      • 1970-01-01
      相关资源
      最近更新 更多