如何基于CSV数据计算多全球位置间的两两距离?
如何迭代处理CSV中的经纬度数据,计算多个位置间的两两距离
你已经有了一个可靠的球面距离计算函数,现在要扩展到多位置的两两配对计算对吧?其实只需要两步核心操作:读取解析CSV数据,生成所有不重复的位置组合来调用你的函数。下面是具体的实现方案:
方法步骤
- 导入必要模块:除了你用到的
math,还需要csv(或更便捷的pandas)读取数据,以及itertools.combinations生成两两组合。 - 读取预处理CSV数据:提取位置名称和经纬度,转换成便于计算的格式(比如用元组存储坐标)。
- 生成组合并计算距离:用
combinations获取无序位置对(避免重复计算如(A,B)和(B,A)),逐个调用global_distance函数。
完整代码示例
方案1:使用标准库csv(无需额外依赖)
import math import csv from itertools import combinations def global_distance(location1, location2): lat1, lon1 = location1 lat2, lon2 = location2 radius = 6371 # 地球半径,单位:公里 dlat = math.radians(lat2 - lat1) dlon = math.radians(lon2 - lon1) a = math.sin(dlat/2) * math.sin(dlat/2) + math.cos(math.radians(lat1)) \ * math.cos(math.radians(lat2)) * math.sin(dlon/2) * math.sin(dlon/2) c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a)) d = radius * c return d # 读取CSV文件(假设文件名为locations.csv) locations = [] with open('locations.csv', 'r', newline='') as file: reader = csv.DictReader(file) for row in reader: # 将经纬度从字符串转为浮点数,存储位置名称和坐标 locations.append({ 'name': row['Location'], 'coords': (float(row['Lat1']), float(row['Long1'])) }) # 遍历所有两两组合并计算距离 for loc1, loc2 in combinations(locations, 2): distance = global_distance(loc1['coords'], loc2['coords']) print(f"({loc1['name']}, {loc2['name']}) 之间的距离:{distance:.2f} 公里")
方案2:使用pandas(更简洁,适合大数据量)
如果已安装pandas,这个方案效率更高:
import math import pandas as pd from itertools import combinations def global_distance(location1, location2): lat1, lon1 = location1 lat2, lon2 = location2 radius = 6371 # 地球半径,单位:公里 dlat = math.radians(lat2 - lat1) dlon = math.radians(lon2 - lon1) a = math.sin(dlat/2) * math.sin(dlat/2) + math.cos(math.radians(lat1)) \ * math.cos(math.radians(lat2)) * math.sin(dlon/2) * math.sin(dlon/2) c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a)) d = radius * c return d # 读取CSV数据 df = pd.read_csv('locations.csv') # 生成包含名称和坐标的列表 location_pairs_source = list(zip(df['Location'], df['Lat1'], df['Long1'])) # 计算并输出所有两两距离 for (name1, lat1, lon1), (name2, lat2, lon2) in combinations(location_pairs_source, 2): distance = global_distance((lat1, lon1), (lat2, lon2)) print(f"({name1}, {name2}) 之间的距离:{distance:.2f} 公里")
直接使用给定数据(无需CSV文件)
如果不想创建文件,可直接构造数据列表:
# 直接使用你提供的三个位置数据 locations_data = [ {'Location': 'A', 'Lat1': 55.322, 'Long1': -117.17}, {'Location': 'B', 'Lat1': 57.316, 'Long1': -117.456}, {'Location': 'C', 'Lat1': 54.275, 'Long1': -116.567} ] locations = [{'name': item['Location'], 'coords': (item['Lat1'], item['Long1'])} for item in locations_data] # 组合计算部分 for loc1, loc2 in combinations(locations, 2): distance = global_distance(loc1['coords'], loc2['coords']) print(f"({loc1['name']}, {loc2['name']}) 之间的距离:{distance:.2f} 公里")
关键说明
itertools.combinations(locations, 2):生成所有长度为2的不重复组合,正好对应你需要的(A,B)、(A,C)、(B,C),避免冗余计算。- 经纬度类型转换:CSV读取的经纬度默认是字符串,必须转为浮点数才能进行数学运算,否则会报错。
- 结果格式化:用
:.2f保留两位小数,让输出更直观。
内容的提问来源于stack exchange,提问作者user_01
相关产品推荐
相关产品推荐

