使用 pandas 中的 UTM 坐标计算数据框的距离
Calculate distance a dataframe with UTM coordinates in pandas
我有一个巨大的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上下车之间的距离。我的问题与这个问题 () 非常相似但又有所不同。我的预期结果如下所示:
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
.......
感谢您的帮助。
解决此问题的一种方法,假设输入干净且正确,将使用 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_1
和 Anotation_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
...)
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']]
我将旋转数据框:
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
我正在使用 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)
我有一个巨大的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上下车之间的距离。我的问题与这个问题 (
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
.......
感谢您的帮助。
解决此问题的一种方法,假设输入干净且正确,将使用 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_1
和 Anotation_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
...)
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']]
我将旋转数据框:
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
我正在使用 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)