1

I am trying to find the distance between every consecutive points in a GeoPandas dataframe. Let's say we have the following data frame:

import pandas as pd
import geopandas

data=pd.DataFrame()
data['lat']=[42,42.1,43,43.2,43.9]
data['lon']=[-120,-119,-118.2,-118,-117.2]
data_gpd=geopandas.GeoDataFrame(data,geometry=geopandas.points_from_xy(data.lon,data.lat),crs={'init' :'epsg:4326'})
data_gpd=data_gpd.to_crs({'init': 'epsg:6340'})  #converted to a meter based CRS

Now I want to find the distance between consecutive points and add it to the data to have something like this (the values are not actual and are only examples):

data['distance_from_previous']=['nan',12000,13000,25000,11000]
  • 1. What you want to do is iterate over the rows of the DF and get two points, 2. Calculate the distance between 1,2 3. Add that number to a collection, 4. Replace point 1 with 2, repeat. – Dheeraj Chand Jan 17 at 2:36
2

There are many solutions to iterate over (Geo)DataFrame row pairs (see Pandas iterate over DataFrame row pairs for example)

1) by iteration

for (indx1,row1),(indx2,row2) in zip(data_gpd[:-1].iterrows(),data_gpd[1:].iterrows()):
   print(indx1, indx2, row1['geometry'].distance(row2['geometry']))
 0 1 83538.37731261192
 1 2 119611.60785001986
 2 3 27537.56741184871
 3 4 101094.9180373711

or

data_gpd['dist_prev'] = 0
for i in data_gpd.index[:-1]:
      data_gpd.loc[i+1, 'dist_prev'] = data_gpd.loc[i, 'geometry'].distance(data_gpd.loc[i+1, 'geometry'])
print(data_gpd)

    lat    lon                    geometry                    dist_prev
0  42.0 -120.0   POINT (251535.0792857883 4654130.891206848)      0
1  42.1 -119.0   POINT (334620.8849107226 4662814.749086842)  83538.377313
2  43.0 -118.2   POINT (402189.4662092684 4761513.399299338)  119611.607850
3  43.2 -118.0   POINT (418756.2450509258 4783510.204925923)  27537.567412
4  43.9 -117.2   POINT (483938.2692632438 4860785.596691785)  101094.918037

2) with pandas.concat

import pandas as pd
from shapely.geometry import shape
df_merged = pd.concat([data_gpd, data_gpd.shift(1).add_prefix('pre_')], axis=1)
df_merged["distance"] = df_merged[:-1].apply (lambda row: row.geometry.distance(shape(row.pre_geometry)), axis=1)
print(df_merged)
   lat    lon           geometry                           pre_lat pre_lon           pre_geometry                      distance
0  42    -120    POINT (251535.0792857883 4654130.891206848)  nan    nan               nan                                nan
1  42.1  -119    POINT (334620.8849107226 4662814.749086842)  42    -120    POINT (251535.0792857883 4654130.891206848)  83538.4
2  43    -118.2  POINT (402189.4662092684 4761513.399299338)  42.1  -119    POINT (334620.8849107226 4662814.749086842)  119612
3  43.2  -118    POINT (418756.2450509258 4783510.204925923)  43    -118.2  POINT (402189.4662092684 4761513.399299338)  27537.6
4  43.9  -117.2  POINT (483938.2692632438 4860785.596691785)  43.2  -118    POINT (418756.2450509258 4783510.204925923)  101095

print(df_merged["distance"]) 
0              NaN
1     83538.377313
2    119611.607850
3     27537.567412
4    101094.918037
Name: distance, dtype: float64

3) groupby by "adjacency" (Perform function on pairs of rows in Pandas dataframe)

g = data_gpd.groupby(data_gpd.index // 2)
# first group
print(g.geometry.get_group(0))
0    POINT (251535.0792857883 4654130.891206848)
1    POINT (334620.8849107226 4662814.749086842)
Name: geometry, dtype: object
# therefore
print(g.geometry.get_group(0)[0].distance(g.geometry.get_group(0)[1]))
83538.37731261192

The problem of this approach is that not all pairs of points are recognized

print(g.groups)
{0: Int64Index([0, 1], dtype='int64'), 1: Int64Index([2, 3], dtype='int64'), 2: Int64Index([4], dtype='int64')}

The distances between points 1 and 2 and 3 and 4 are not calculated (groups different)

    -

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.