如何同时合并 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/