合并数据#

在GeoPandas中有两种合并数据集的方法 - 属性连接和空间连接。

在属性连接中,GeoSeriesGeoDataFrame 基于一个共同变量与普通的 pandas.Seriespandas.DataFrame 结合。这类似于 pandas 中的普通合并或连接。

在空间连接中,来自两个 GeoSeriesGeoDataFrame 的观测值根据它们之间的空间关系被组合在一起。

在以下示例中,使用了这些数据集:

In [1]: import geodatasets

In [2]: chicago = geopandas.read_file(geodatasets.get_path("geoda.chicago_commpop"))

In [3]: groceries = geopandas.read_file(geodatasets.get_path("geoda.groceries"))

# For attribute join
In [4]: chicago_shapes = chicago[['geometry', 'NID']]

In [5]: chicago_names = chicago[['community', 'NID']]

# For spatial join
In [6]: chicago = chicago[['geometry', 'community']].to_crs(groceries.crs)

附加#

附加 GeoDataFrameGeoSeries 使用 pandas concat() 函数。请记住,附加的几何列需要具有相同的 CRS。

# Appending GeoSeries
In [7]: joined = pd.concat([chicago.geometry, groceries.geometry])

# Appending GeoDataFrames
In [8]: douglas = chicago[chicago.community == 'DOUGLAS']

In [9]: oakland = chicago[chicago.community == 'OAKLAND']

In [10]: douglas_oakland = pd.concat([douglas, oakland])

属性连接#

属性连接是通过使用 merge() 方法来完成的。一般来说,建议从空间数据集调用 merge() 方法。也就是说,如果 GeoDataFrameleft 参数中,独立的 pandas.merge() 函数将可以工作;如果 DataFrameleft 参数中,而 GeoDataFrameright 位置,结果将不再是 GeoDataFrame

例如,考虑以下合并,它将完整名称添加到一个 GeoDataFrame,该 GeoDataFrame 最初仅为每个几何体具有区域 ID,通过与一个 DataFrame 合并。

# `chicago_shapes` is GeoDataFrame with community shapes and area IDs
In [11]: chicago_shapes.head()
Out[11]: 
                                            geometry  NID
0  MULTIPOLYGON (((-87.609140876 41.844692503, -8...   35
1  MULTIPOLYGON (((-87.592152839 41.816929346, -8...   36
2  MULTIPOLYGON (((-87.628798237 41.801893034, -8...   37
3  MULTIPOLYGON (((-87.606708126 41.816813771, -8...   38
4  MULTIPOLYGON (((-87.592152839 41.816929346, -8...   39

# `chicago_names` is DataFrame with community names and area ID
In [12]: chicago_names.head()
Out[12]: 
         community  NID
0          DOUGLAS   35
1          OAKLAND   36
2      FULLER PARK   37
3  GRAND BOULEVARD   38
4          KENWOOD   39

# Merge with `merge` method on shared variable (area ID):
In [13]: chicago_shapes = chicago_shapes.merge(chicago_names, on='NID')

In [14]: chicago_shapes.head()
Out[14]: 
                                            geometry  NID        community
0  MULTIPOLYGON (((-87.609140876 41.844692503, -8...   35          DOUGLAS
1  MULTIPOLYGON (((-87.592152839 41.816929346, -8...   36          OAKLAND
2  MULTIPOLYGON (((-87.628798237 41.801893034, -8...   37      FULLER PARK
3  MULTIPOLYGON (((-87.606708126 41.816813771, -8...   38  GRAND BOULEVARD
4  MULTIPOLYGON (((-87.592152839 41.816929346, -8...   39          KENWOOD

空间连接#

在空间连接中,两个几何对象根据它们之间的空间关系进行合并。

# One GeoDataFrame of communities, one of grocery stores.
# Want to merge to get each grocery's community.
In [15]: chicago.head()
Out[15]: 
                                            geometry        community
0  MULTIPOLYGON (((1181573.249800048 1886828.0393...          DOUGLAS
1  MULTIPOLYGON (((1186289.355600054 1876750.7332...          OAKLAND
2  MULTIPOLYGON (((1176344.998000037 1871187.5456...      FULLER PARK
3  MULTIPOLYGON (((1182322.042900046 1876674.7304...  GRAND BOULEVARD
4  MULTIPOLYGON (((1186289.355600054 1876750.7332...          KENWOOD

In [16]: groceries.head()
Out[16]: 
   OBJECTID  ...                                           geometry
0        16  ...  MULTIPOINT ((1168268.671671558 1933554.3504257...
1        18  ...  MULTIPOINT ((1162302.617919334 1832900.2240279...
2        22  ...  MULTIPOINT ((1173317.042329894 1895425.4259547...
3        23  ...  MULTIPOINT ((1168996.475130927 1898801.4056401...
4        27  ...  MULTIPOINT ((1176991.988724414 1847262.4228848...

[5 rows x 8 columns]

# Execute spatial join
In [17]: groceries_with_community = groceries.sjoin(chicago, how="inner", predicate='intersects')

In [18]: groceries_with_community.head()
Out[18]: 
   OBJECTID     Ycoord  ...  index_right       community
0        16  41.973266  ...           30          UPTOWN
1        18  41.696367  ...           73     MORGAN PARK
2        22  41.868634  ...           28  NEAR WEST SIDE
3        23  41.877590  ...           28  NEAR WEST SIDE
4        27  41.737696  ...           39         CHATHAM

[5 rows x 10 columns]

GeoPandas 提供了两个空间连接函数:

注意

出于历史原因,这两种方法也作为顶级函数sjoin()sjoin_nearest()可用。建议使用方法,因为这些函数在未来可能会被弃用。

二元谓词连接#

二元谓词连接可以通过 GeoDataFrame.sjoin() 获得。

GeoDataFrame.sjoin() 有两个核心参数: howpredicate

谓词

这个 predicate 参数指定了GeoPandas如何根据对象之间的几何关系决定是否将一个对象的属性连接到另一个对象。

predicate的值对应于几何二元谓词的名称,并且依赖于空间索引的实现。

GeoPandas中默认的空间索引目前支持以下值用于 predicate,这些值定义在 Shapely documentation:

  • 相交

  • 包含

  • 内部

  • 触碰

  • 交叉

  • 重叠

怎么

how 参数指定将发生的连接类型,以及在结果中保留哪个几何图形 GeoDataFrame。它接受以下选项:

  • left: 使用您提供的第一个(或left_dfGeoDataFrame中的索引 到GeoDataFrame.sjoin(); 仅保留left_df几何列

  • right: 使用第二个的索引(或 right_df);仅保留 right_df 几何列

  • inner:使用两个 GeoDataFrame 的索引值交集;仅保留 left_df 几何列

注意,可以通过将几何操作与空间连接结合来研究更复杂的空间关系。 例如,要查找给定点在一定距离内的所有多边形,可以首先使用buffer()方法将每个 点扩展为适当半径的圆,然后将这些缓冲圆与相关多边形相交。

最近邻连接#

基于邻近的连接可以通过 GeoDataFrame.sjoin_nearest() 进行。

GeoDataFrame.sjoin_nearest()GeoDataFrame.sjoin() 共享 how 参数,并且包含两个额外的参数:max_distancedistance_col

最大距离

max_distance 参数指定了匹配几何图形的最大搜索半径。这在某些情况下可能会对性能产生相当大的影响。 如果可以的话,强烈建议您使用此参数。

距离列

如果设置,结果 GeoDataFrame 将包含一个具有该名称的列,包含输入几何与最近几何之间计算的距离。