You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用haversine地理定位双循环生成成员到地点距离排名DataFrame

问题核心原因

你原有代码的问题在于两层循环缩进错误,且没有对每个成员的计算结果做隔离,所有成员的距离数据混在一起排序,自然无法得到每个成员单独的排序结果。以下是可直接运行的修正方案:

方案1:基于你原有逻辑修改的循环版本

import pandas as pd
import numpy as np

# 这里默认你已经实现了haversine距离计算函数,以下是标准实现可直接用
def haversine(lon1, lat1, lon2, lat2):
    # 距离单位为公里,可根据需求调整返回值系数
    lon1, lat1, lon2, lat2 = map(np.radians, [lon1, lat1, lon2, lat2])
    dlon = lon2 - lon1
    dlat = lat2 - lat1
    a = np.sin(dlat/2)**2 + np.cos(lat1) * np.cos(lat2) * np.sin(dlon/2)**2
    c = 2 * np.arcsin(np.sqrt(a))
    return c * 6371

# 存储所有成员的单行结果
all_member_res = []

for m_idx in range(len(members)):
    # 取当前成员信息
    cur_member = members.iloc[m_idx]
    member_id = cur_member['member_id']
    # 计算当前成员到所有地点的距离
    dist_list = []
    for s_idx in range(len(locations)):
        cur_loc = locations.iloc[s_idx]
        dist = haversine(
            lon1 = cur_member['longitude'],
            lat1 = cur_member['latitude'],
            lon2 = cur_loc['longitude'],
            lat2 = cur_loc['latitude']
        )
        dist_list.append({
            'location': cur_loc['location'],
            'distance': dist
        })
    # 按距离升序排序
    cur_member_dist = pd.DataFrame(dist_list).sort_values('distance', ascending=True).reset_index(drop=True)
    # 拼接为预期的宽表行结构
    res_row = {
        'member': member_id,
        'location_1': cur_member_dist.loc[0, 'location'],
        'distance_1': round(cur_member_dist.loc[0, 'distance']),
        'location_2': cur_member_dist.loc[1, 'location'],
        'distance_2': round(cur_member_dist.loc[1, 'distance']),
        'location_3': cur_member_dist.loc[2, 'location'],
        'distance_3': round(cur_member_dist.loc[2, 'distance'])
    }
    all_member_res.append(res_row)

# 生成最终结果表
results = pd.DataFrame(all_member_res)

方案2:更高效的向量化写法,无需嵌套循环

通过笛卡尔积一次性生成所有成员+地点的组合,批量计算距离后直接格式转换,性能远高于嵌套循环,适合数据量更大的场景:

# 生成所有成员和地点的全量组合
cross_df = members.assign(tmp=1).merge(locations.assign(tmp=1), on='tmp', suffixes=('_member', '_loc')).drop('tmp', axis=1)
# 批量计算所有组合的距离
cross_df['distance'] = cross_df.apply(lambda x: haversine(x['longitude_member'], x['latitude_member'], x['longitude_loc'], x['latitude_loc']), axis=1)
# 按成员分组后给距离做升序排名
cross_df['rank'] = cross_df.groupby('member_id')['distance'].rank(method='first', ascending=True).astype(int)
# 转换为预期的宽表结构
results = cross_df.pivot(index='member_id', columns='rank', values=['location', 'distance']).reset_index()
# 调整列名和格式,和示例输出对齐
results.columns = [f'{col[0]}_{col[1]}' if col[1] else col[0] for col in results.columns]
results = results.rename(columns={'member_id': 'member'}).sort_values('member').reset_index(drop=True)
results[['distance_1', 'distance_2', 'distance_3']] = results[['distance_1', 'distance_2', 'distance_3']].round().astype(int)

两种方案运行后得到的results表和你给出的预期输出结构完全一致。

内容的提问来源于stack exchange,提问作者June Smith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.18 11:36:02