Distance Betweeen Coordinates Python Vs R Computation Time
Solution 1:
You are using .apply()
, which uses a simple loop to run your function for each and every row. The distance calculation is done entirely in Python (geopy
uses geographiclib
which appears to be written in Python only). Non-vectorised distance calculations are slow, what you need is a vectorised solution using compiled code, just like when calculating the Haversine distance.
pyproj
offers verctorised WSG84 distance calculations (the methods of the pyproj.Geod
class accept numpy arrays) and wraps the PROJ4 library, meaning it runs these calculations in native machine code:
from pyproj import Geod
# split out coordinates into separate columnsdf[['or_lat', 'or_lon']] = pd.DataFrame(df['or'].tolist(), index=df.index)
df[['new_lat', 'new_lon']] = pd.DataFrame(df['new'].tolist(), index=df.index)
wsg84 = Geod(ellps='WGS84')
# numpy matrix of the lon / lat columns, iterable in column order
or_and_new = df[['or_lon', 'or_lat', 'new_lon', 'new_lat']].to_numpy().T
df['d2city2'] = wsg84.inv(*or_and_new)[-1] / 1000 # as km
This clocks in at considerably better times:
>>>from timeit import Timer>>>count, total = Timer(..."wsg84.inv(*df[['or_lon', 'or_lat', 'new_lon', 'new_lat']].to_numpy().T)[-1] / 1000",...'from __main__ import wsg84, df'...).autorange()>>>total / count * 10 ** 3# milliseconds
66.09873340003105
66 milliseconds to calculate 100k distances, not bad!
To make the comparison objective, here is your geopy
/ df.apply()
version on the same machine:
>>>count, total = Timer("df.apply(lambda x: geodesic(x['or'], x['new']).km, axis=1)", 'from __main__ import geodesic, df').autorange()>>>total / count * 10 ** 3# milliseconds
25844.119450000107
25.8 seconds, not even in the same ballpark.
Post a Comment for "Distance Betweeen Coordinates Python Vs R Computation Time"