I have a python dataset that has the following structure:
cluster pts lon lat
0 5 45 24
1 6 47 23
2 10 45 20
As you can see, I have a column that refers to a cluster, the number of points within a cluster, the representative latitude of the cluster and the representative longitude of the cluster. In the whole dataframe I have 140 clusters.
Now I would like to calculate for each cluster the following operation by means of a combinatorial:
𝑤𝑒𝑖𝑔ℎ𝑡(𝑖,𝑗)=−𝑛𝑖+𝑛𝑗/𝑑𝑖𝑠𝑡(𝑖,𝑗)
where i refers to a cluster and j to another. where n refers to the number of pts
On the one hand it does the sum of the points between cluster i and cluster j, and in the denominator it calculates by means of haversine the distance between the two clusters taking into account their representative coordinates.
I've started by coming up with a code that uses itertools, but I have problems to continue. Any idea?
from itertools import combinations
for c in combinations(df['cluster'],2):
sum_pts=
distance=
weight=-(sum_pts/distance)
print(c,weight)
If you care about performance you may want to use merge and vectorized operations.
import numpy as np
import pandas as pd
def haversine_distance(lat1, lon1, lat2, lon2):
R = 6372800 # Earth radius in meters
phi1, phi2 = np.radians(lat1), np.radians(lat2)
dphi = np.radians(lat2 - lat1)
dlambda = np.radians(lon2 - lon1)
a = np.sin(dphi / 2) ** 2 + np.cos(phi1) * np.cos(phi2) * np.sin(dlambda / 2) ** 2
return 2 * R * np.arctan2(np.sqrt(a), np.sqrt(1 - a))
df = pd.DataFrame({
'cluster': [0, 1, 2],
'pts': [5, 6, 10],
'lat': [45, 47, 45],
'lon': [24, 23, 20],
})
df = pd.merge(df, df, suffixes=('_1', '_2'), how="cross")
df = df[df['cluster_1'] != df['cluster_2']]
df["weight"] = -df['pts_1'] + df['pts_2'] / haversine_distance(df['lat_1'], df['lon_1'], df['lat_2'], df['lon_2'])