如何用itertools组合学对聚类数据集执行加权计算?
问题描述
我有一个Python数据集,结构如下:
cluster pts lon lat 0 5 45 24 1 6 47 23 2 10 45 20
该数据集包含聚类编号(cluster)、聚类内点数(pts)、聚类代表经度(lon)和纬度(lat)字段,总计140个聚类。
我希望通过组合学方法为每对聚类计算以下加权值:
weight(i,j) = -(n_i + n_j)/dist(i,j)
其中i和j代表不同聚类,n为对应聚类的pts数值,分母dist(i,j)是通过haversine公式计算的两聚类代表坐标间的距离。
我已编写了使用itertools的初始代码,但后续实现遇到问题,寻求解决思路:
from itertools import combinations for c in combinations(df['cluster'],2): sum_pts= distance= weight=-(sum_pts/distance) print(c,weight)
解决思路与完整实现
1. 实现Haversine距离计算函数
Haversine公式用于计算球面上两点的大圆距离,需先将经纬度从度数转换为弧度,再代入公式计算:
import math def haversine(lon1, lat1, lon2, lat2): # 经纬度转换为弧度 lon1 = math.radians(lon1) lat1 = math.radians(lat1) lon2 = math.radians(lon2) lat2 = math.radians(lat2) # Haversine核心计算 dlon = lon2 - lon1 dlat = lat2 - lat1 a = math.sin(dlat/2)**2 + math.cos(lat1) * math.cos(lat2) * math.sin(dlon/2)**2 c = 2 * math.asin(math.sqrt(a)) # 地球半径(单位:千米,可按需调整为米等) r = 6371 return c * r
2. 完善组合遍历逻辑
先将数据框的cluster设为索引,方便快速查询聚类对应的属性值,再遍历所有聚类对完成计算:
import pandas as pd from itertools import combinations # 假设数据集存储在df中,设置cluster为索引 df = df.set_index('cluster') # 遍历所有不重复的聚类对 for cluster_i, cluster_j in combinations(df.index, 2): # 获取两个聚类的点数之和 n_i = df.loc[cluster_i, 'pts'] n_j = df.loc[cluster_j, 'pts'] sum_pts = n_i + n_j # 获取经纬度并计算距离 lon1, lat1 = df.loc[cluster_i, ['lon', 'lat']] lon2, lat2 = df.loc[cluster_j, ['lon', 'lat']] distance = haversine(lon1, lat1, lon2, lat2) # 处理距离为0的特殊情况(避免除以0错误) if distance == 0: weight = 0 # 可根据业务需求调整默认值 else: weight = -(sum_pts / distance) print(f"聚类对({cluster_i}, {cluster_j})的加权值: {weight}")
3. 优化建议(可选)
- 若需后续分析,可将结果存储为DataFrame:
results = [] for cluster_i, cluster_j in combinations(df.index, 2): n_i = df.loc[cluster_i, 'pts'] n_j = df.loc[cluster_j, 'pts'] sum_pts = n_i + n_j lon1, lat1 = df.loc[cluster_i, ['lon', 'lat']] lon2, lat2 = df.loc[cluster_j, ['lon', 'lat']] distance = haversine(lon1, lat1, lon2, lat2) weight = -(sum_pts / distance) if distance != 0 else 0 results.append({ 'cluster_i': cluster_i, 'cluster_j': cluster_j, 'weight': weight }) result_df = pd.DataFrame(results) print(result_df)
- 针对140个聚类(约9730对计算),若追求效率可改用向量化库(如
numpy)预计算距离矩阵,再批量生成加权值。
内容的提问来源于stack exchange,提问作者Stackoverflow Stackoverflow
相关产品推荐
相关产品推荐

