Pretty sure this is what you're looking for. I used clustering from the sklearn package since this is essentially the same problem as this question: Split polygons in a shapefile based on distance
import pandas as pd
import geopandas as gpd
import shapely
from sklearn.cluster import AgglomerativeClustering
def cluster_shapes_by_distance(geodf, distance, check_crs=False):
"""
Make groups for all shapes within a defined distance. For a shape to be
excluded from a group, it must be greater than the defined distance
from *all* shapes in the group.
Distances are calculated using shape centroids.
Parameters
----------
geodf : data.frame
A geopandas data.frame of polygons. Should be a projected CRS where the
unit is in meters.
distance : float
Maximum distance between elements. In meters.
check_crs : bool
Confirm that the CRS of the geopandas dataframe is projected. This
function should not be run with lat/lon coordinates.
Returns
-------
np.array
Array of numeric labels assigned to each row in geodf.
"""
if check_crs:
assert geodf.crs.is_projected, 'geodf should be a projected crs with meters as the unit'
centers = [p.centroid for p in geodf.geometry]
centers_xy = [[c.x, c.y] for c in centers]
cluster = AgglomerativeClustering(n_clusters=None,
linkage='single',
affinity='euclidean',
distance_threshold=distance)
cluster.fit(centers_xy)
return cluster.labels_
#---------------------------
geoms = ['POINT (-525919.001 7186220.048)', 'POINT (-525950.054 7186212.882)',
'POINT (-526009.173 7186211.688)', 'POINT (-526009.173 7186211.688)',
'POINT (-526009.173 7186211.688)']
geoms = [shapely.wkt.loads(s) for s in geoms]
df = gpd.GeoDataFrame(
{'captured_at': [1632410217000, 1632410219000, 1632410221000, 1632410223000, 1632410225000]},
geometry = gpd.GeoSeries(geoms),
)
df['group'] = cluster_shapes_by_distance(df, distance=20) # 125km
# Within each group keep the most recent.
df = df.groupby('group').apply(lambda x: x.iloc[x.captured_at.argmax()])