【问题标题】:Calculating pairwise distances for Shapely geometry objects计算 Shapely 几何对象的成对距离
【发布时间】:2020-09-14 19:41:56
【问题描述】:

我在常规的 stackoverflow 而不是 stackexchange GIS 上问这个问题,因为我的问题更多是 scikit-learn,而不是任何与 GIS 相关的库。

我有一个包含多边形的 GeoDataFrame(一个 Pandas GeoDataFrame,但具有额外的几何功能),我想计算它们之间的成对距离。我也在与 scikit-learn 合作,似乎他们为此有一些很好的优化函数,而且您似乎也可以指定一个可调用函数来进行实际距离计算,这很好,因为我可以(我认为)输出距离矩阵时,只需使用 Shapely 的.distance() 方法即可获取多边形之间的距离。该方法计算两个几何之间的几何距离。

但是,我不知道如何实现自定义可调用函数。这是我目前所拥有的:

import geopandas as gpd
from random import uniform
from shapely.geometry import Point
from sklearn.metrics import pairwise_distances

# Define polygon to polygon distance callable
def poly_distance(poly1, poly2):
    return poly1.distance(poly2)

# Make some points and buffer them into polygons
geoms = [Point(uniform(0, 100), uniform(0, 100)) for i in range(100)]
gdf = gpd.GeoDataFrame(geoms, columns=["geometry"], geometry="geometry")
gdf[gdf.geometry.name] = gdf.buffer(1)

X = gdf[gdf.geometry.name].to_numpy()

result = pairwise_distances(X, poly_distance)

我认为这会起作用,因为我正在指定一个函数,该函数将从生成的 numpy 数组 (X) 中获取两个元素并返回它们之间的浮点距离。但它抱怨:

TypeError: float() argument must be a string or a number, not 'Polygon'

docs 确实说:

callable 应该将来自 X 的两个数组作为输入,并返回一个指示它们之间距离的值。

但我不知道如何将其转换为函数所需的格式。我还尝试了X的以下定义:

X = np.array([gdf[gdf.geometry.name].to_numpy()])
X = np.transpose(np.array([gdf[gdf.geometry.name].to_numpy()]))

但他们都没有工作。

【问题讨论】:

    标签: python scikit-learn geopandas


    【解决方案1】:

    sklearn 指标期望参数 x 具有可转换为浮点数的有效 dtype。如果您看到源代码,它会在计算它们之间的距离之前将数组转换为浮点数。

    由于您的 X 包含一个多边形对象,因此在将数组转换为浮点数时会出错。

    但是,您可以构建自己的 pair_wise 函数,该函数将 polygon array 和 distance function 作为输入,并将 distance matrix 作为输出。

    代码:

    import geopandas as gpd
    from random import uniform
    from shapely.geometry import Point
    import numpy as np
    
    # Define polygon to polygon distance callable
    def poly_distance(poly1, poly2):
        return poly1.distance(poly2)
    
    # Make some points and buffer them into polygons
    geoms = [Point(uniform(0, 100), uniform(0, 100)) for i in range(100)]
    gdf = gpd.GeoDataFrame(geoms, columns=["geometry"], geometry="geometry")
    gdf[gdf.geometry.name] = gdf.buffer(1)
    X = gdf[gdf.geometry.name].to_numpy()
    
    def pair_wise(x, function):
      distance_matrix = []
      for element in x:
        distance_matrix.append([function(element, item) for item in x])
      return np.array(distance_matrix)
    
    pair_wise(X, poly_distance)
    

    【讨论】:

    • 不幸的是相当慢,这就是为什么我希望我可以使用 sklearn 的一些东西,因为我希望使用它的一些内部优化。但它在技术上确实有效。
    猜你喜欢
    • 2016-04-06
    • 2013-09-02
    • 2015-01-13
    • 2014-04-29
    • 1970-01-01
    • 2021-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多