python - 同时合并点几何和其他列上的 GeoDataFrame

标签 python pandas shapely geopandas

如何同时合并 Point 几何图形和任意其他列上的两个 GeoDataFrame?我意识到这个任务对于除点之外的所有其他几何图形来说都是不明确的,因为“相等”对于线和多边形没有明确定义,但仍然如此。

如果我只是尝试 gdf2.merge(gdf),以下 MWE 会抛出错误,正确地提示

unhashable type: 'Point'.

如何解决这个问题?

import geopandas as gpd
import pandas as pd
from io import StringIO
import shapely

df = pd.read_csv(StringIO('''
Name Value x y
'a' 1.5 0. 0.
'b' 22  0. 1.
'c' 0.2 0. 1.
'''),sep=r"\s*",engine='python')

df2 = pd.read_csv(StringIO('''
Name OtherValue x y
'a' 9.9 0. 0.
'b' 4.5 0. 1.
'c' 2e3 1. 1.
'''),sep=r"\s*",engine='python')

def dataframe_to_geodataframe(df):
    geometry = [shapely.geometry.Point(xy) for xy in zip(df.x, df.y)]
    df = df.drop(['x','y'], axis=1)
    gdf = gpd.GeoDataFrame(df, geometry=geometry)
    return gdf

gdf = dataframe_to_geodataframe(df)
gdf2 = dataframe_to_geodataframe(df2)

gdf.merge(gdf2,how='left')

理想情况下输出类似于

  Name  Value     geometry OtherValue
0  'a'    1.5  POINT (0 0)        9.9
1  'b'   22.0  POINT (0 1)        4.5
2  'c'    0.2  POINT (0 1)        NaN

(当然取决于how关键字)。

(我确实意识到在转换回普通的 pandas DataFrames 后可以轻松完成此操作,但我觉得应该有一种方法可以在不来回转换的情况下完成此操作。)

最佳答案

一种(也许是肮脏的)方法是通过扩展类 shapely.geometry.Point 来使 Point 可哈希:

class HPoint(shapely.geometry.Point):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    def __hash__(self):
       return hash(tuple(self.coords))

这是基于以下事实:Point 的相等运算符(通过父类 BaseGeometry 提供)只是 compares坐标元组。

然后你可以使用这个类:

def dataframe_to_geodataframe(df):
    geometry = [HPoint(xy) for xy in zip(df.x, df.y)]
    df = df.drop(['x','y'], axis=1)
    gdf = gpd.GeoDataFrame(df, geometry=geometry)
    return gdf

gdf = dataframe_to_geodataframe(df)
gdf2 = dataframe_to_geodataframe(df2)

print(gdf2.merge(gdf, how='right'))

产生:

  Name  OtherValue     geometry  Value
0  'a'         9.9  POINT (0 0)    1.5
1  'b'         4.5  POINT (0 1)   22.0
2  'c'         NaN  POINT (0 1)    0.2

关于python - 同时合并点几何和其他列上的 GeoDataFrame,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52371968/

相关文章:

python - 使用 AWS API 网关触发在 EC2 实例上运行的 python 脚本并传递参数

python - 如何创建一个空的 pandas DataFrame,并为每列分配不同的数据类型?

python - 如果任何行包含特定字符串,则选择列

python - Numpy 聚合到 bin 中,然后计算总和?

python - 在不阻止执行的情况下显示和更新 MatPlotLib 图形

python - 修改pip安装路径

python - 模块 'shapely' 没有属性 'geometry' 错误

python - 如何从python的中心点创建坐标网格?

python - 为什么 SQLAlchemy 不更新 Flask WSGI 服务器中的行值?

python - 如何从匀称的点列表中创建匀称的多边形?