如何计算GeoPandas中两个点GeoDataFrame的所有点间距离?
计算两个GeoDataFrame所有点对的距离
我来帮你搞定这个计算所有点对距离的问题!你遇到的情况很典型:gdf_1.distance(gdf_2)是按索引对齐来计算元素级距离的,当两个GeoDataFrame长度不同、索引不匹配时,就会出现NaN值和警告,它只处理同索引的点对,完全不是我们要的所有组合。下面给你几种实用的解决方案:
方法1:生成笛卡尔积(所有点对组合)
这种方法最直观,能直接得到所有点对的索引组合和对应的距离,适合中等规模的数据:
import geopandas as gpd import pandas as pd # 你的测试数据 gdf_1 = gpd.GeoDataFrame(geometry=gpd.points_from_xy([0, 0, 0], [0, 90, 120])) gdf_2 = gpd.GeoDataFrame(geometry=gpd.points_from_xy([0, 0], [0, -90])) # 给两个GeoDataFrame添加唯一标识列(方便后续对应点对) gdf_1['id1'] = gdf_1.index gdf_2['id2'] = gdf_2.index # 生成所有点对的笛卡尔积(cross join) cross_pairs = gdf_1.merge(gdf_2, how='cross') # 计算每一对点的距离 cross_pairs['distance'] = cross_pairs.apply(lambda row: row['geometry_x'].distance(row['geometry_y']), axis=1) # 查看结果(只保留关键列) print(cross_pairs[['id1', 'id2', 'distance']])
运行后会输出6行结果(3×2的所有组合),每一行对应gdf_1的一个点和gdf_2的一个点的距离,完全没有NaN。
方法2:用apply生成距离矩阵
如果需要以矩阵形式展示距离(行是gdf_1的点,列是gdf_2的点),可以用apply来实现:
# 对gdf_1中的每个点,计算它到gdf_2所有点的距离 distance_matrix = gdf_1.geometry.apply(lambda point: gdf_2.geometry.distance(point)) # 转换为更易读的DataFrame格式 distance_df = pd.DataFrame(distance_matrix.to_list(), index=gdf_1.index, columns=gdf_2.index) print(distance_df)
这个结果是一个3行2列的矩阵,每个单元格的值就是对应点对的距离,适合需要矩阵分析的场景。
方法3:大数据量下的高效方案
如果你的GeoDataFrame包含成百上千个点,上面两种方法的效率会下降,这时候可以用numpy+scipy的向量化运算来提速:
import numpy as np from scipy.spatial.distance import cdist # 提取两个GeoDataFrame中点的坐标数组 coords1 = np.array([(p.x, p.y) for p in gdf_1.geometry]) coords2 = np.array([(p.x, p.y) for p in gdf_2.geometry]) # 计算所有点对的距离(向量化运算,速度极快) distance_matrix = cdist(coords1, coords2) # 转换为DataFrame distance_df = pd.DataFrame(distance_matrix, index=gdf_1.index, columns=gdf_2.index) print(distance_df)
这种方法基于底层的numpy运算,比apply快几个数量级,非常适合处理大规模数据。
内容的提问来源于stack exchange,提问作者Léonard
相关产品推荐
相关产品推荐

