注意

This page was generated from 入门/介绍.ipynb.
Interactive online version: Binder badge

GeoPandas简介#

这个快速教程介绍了GeoPandas的关键概念和基本特性,帮助您开始您的项目。

概念#

GeoPandas, 顾名思义,通过添加对地理空间数据的支持,扩展了流行的数据科学库 pandas。如果您不熟悉 pandas,我们建议在继续之前快速查看其 入门文档

GeoPandas中的核心数据结构是geopandas.GeoDataFrame,它是pandas.DataFrame的子类,可以存储几何列并执行空间操作。geopandas.GeoSeriespandas.Series的子类,处理几何形状。因此,您的GeoDataFramepandas.Series(传统数据,如数值、布尔、文本等)和geopandas.GeoSeries(几何形状,如点、多边形等)的组合。您可以根据需要拥有任意数量的几何列;与一些典型的桌面GIS软件不同。

geodataframe schema

每个 GeoSeries 可以包含任何几何类型(您甚至可以在一个数组中混合它们),并具有 GeoSeries.crs 属性,该属性存储有关投影的信息(CRS 代表坐标参考系统)。因此,每个 GeoSeriesGeoDataFrame 中可以使用不同的投影,这允许您拥有,例如,同一几何图形的多个版本(不同的投影)。

在一个 GeoDataFrame 中只有一个 GeoSeries 被认为是 活动几何列,这意味着对 GeoDataFrame 应用的所有几何操作都作用于这一列。活动几何列通过 GeoDataFrame.geometry 属性访问。

用户指南

在用户指南中查看更多有关 数据结构 的内容。

让我们看看这些概念在实践中是如何运作的。

读取和写入文件#

首先,我们需要读取一些数据。

读取文件#

假设您有一个包含数据和几何信息的文件(例如 GeoPackage、GeoJSON、Shapefile),您可以使用 geopandas.read_file() 来读取它,该函数会自动检测文件类型并创建一个 GeoDataFrame。本教程使用 "nybb" 数据集,这是一个纽约区的地图,可以通过 geodatasets 包获得。因此,我们使用 geodatasets.get_path() 来下载数据集并检索本地副本的路径。

[1]:
import geopandas
from geodatasets import get_path

path_to_data = get_path("nybb")
gdf = geopandas.read_file(path_to_data)

gdf
[1]:
行政区代码 行政区名称 形状长度 形状面积 几何
0 5 史坦顿岛 330470.010332 1.623820e+09 MULTIPOLYGON (((970217.022 145643.332, 970227....
1 4 皇后区 896344.047763 3.045213e+09 MULTIPOLYGON (((1029606.077 156073.814, 102957...
2 3 布鲁克林 741080.523166 1.937479e+09 MULTIPOLYGON (((1021176.479 151374.797, 102100...
3 1 曼哈顿 359299.096471 6.364715e+08 多边形 (((981219.056 188655.316, 980940....
4 2 布朗克斯 464392.991824 1.186925e+09 MULTIPOLYGON (((1012821.806 229228.265, 101278...

写入文件#

要将 GeoDataFrame 写回文件,使用 GeoDataFrame.to_file()。默认情况下,文件格式由文件扩展名推断(例如 .shp 用于 Shapefile, .geojson 用于 GeoJSON),但您可以通过 driver 关键字显式指定这一点。

[2]:
gdf.to_file("my_file.geojson", driver="GeoJSON")

用户指南

在用户指南中查看更多关于 读取和写入文件 的信息。

简单的访问器和方法#

现在我们有了我们的 GeoDataFrame,可以开始处理它的几何形状。

由于纽约区数据集中只有一个几何列,因此该列自动成为活动几何,应用于GeoDataFrame的空间方法将应用于"geometry"列。

测量面积#

要测量每个多边形(在这个特定情况下是MultiPolygon)的面积,可以访问 GeoDataFrame.area 属性,它返回一个 pandas.Series。请注意 GeoDataFrame.area 只是将 GeoSeries.area 应用于 active 几何列。

但是首先,为了使结果更易于阅读,将区的名称设置为索引:

[3]:
gdf = gdf.set_index("BoroName")
[4]:
gdf["area"] = gdf.area
gdf["area"]
[4]:
BoroName
Staten Island    1.623822e+09
Queens           3.045214e+09
Brooklyn         1.937478e+09
Manhattan        6.364712e+08
Bronx            1.186926e+09
Name: area, dtype: float64

获取多边形边界和中心点#

要获取每个多边形(线串)的边界,可以访问 GeoDataFrame.boundary

[5]:
gdf["boundary"] = gdf.boundary
gdf["boundary"]
[5]:
BoroName
Staten Island    MULTILINESTRING ((970217.022 145643.332, 97022...
Queens           MULTILINESTRING ((1029606.077 156073.814, 1029...
Brooklyn         MULTILINESTRING ((1021176.479 151374.797, 1021...
Manhattan        MULTILINESTRING ((981219.056 188655.316, 98094...
Bronx            MULTILINESTRING ((1012821.806 229228.265, 1012...
Name: boundary, dtype: geometry

由于我们将边界保存为一个新列,现在在同一个 GeoDataFrame中有两个几何列。

我们还可以创建新的几何形状,例如原始几何形状的缓冲区版本(即, GeoDataFrame.buffer(10))或它的中心点:

[6]:
gdf["centroid"] = gdf.centroid
gdf["centroid"]
[6]:
BoroName
Staten Island      POINT (941639.45 150931.991)
Queens           POINT (1034578.078 197116.604)
Brooklyn          POINT (998769.115 174169.761)
Manhattan         POINT (993336.965 222451.437)
Bronx              POINT (1021174.79 249937.98)
Name: centroid, dtype: geometry

测量距离#

我们还可以测量每个中心点与第一个中心点位置的距离。

[7]:
first_point = gdf["centroid"].iloc[0]
gdf["distance"] = gdf["centroid"].distance(first_point)
gdf["distance"]
[7]:
BoroName
Staten Island         0.000000
Queens           103781.535276
Brooklyn          61674.893421
Manhattan         88247.742789
Bronx            126996.283623
Name: distance, dtype: float64

请注意,geopandas.GeoDataFramepandas.DataFrame 的子类, 因此我们可以在地理空间数据集上使用所有的 pandas 功能——我们甚至可以结合属性和几何信息进行数据操作。

例如,要计算上述测量的距离的平均值,可以访问“distance”列并在其上调用mean()方法:

[8]:
gdf["distance"].mean()
[8]:
np.float64(76140.09102166798)

制作地图#

GeoPandas 还可以绘制地图,因此我们可以检查几何体在空间中的样子。要绘制活动几何体,请调用 GeoDataFrame.plot()。要按另一个列进行着色编码,请将该列作为第一个参数传入。在下面的示例中,我们绘制活动几何体列,并按 "area" 列进行着色编码。我们还想显示图例 (legend=True)。

[9]:
gdf.plot("area", legend=True)
[9]:
<Axes: >
../_images/getting_started_introduction_16_1.png

您还可以使用 GeoDataFrame.explore() 以交互方式探索您的数据,它的行为与 plot() 相同,但返回的是一个交互式地图。

[10]:
gdf.explore("area", legend=False)
[10]:
Make this Notebook Trusted to load map: File -> Trust Notebook

将活动几何形状 (GeoDataFrame.set_geometry) 切换为重心,我们可以使用点几何形状绘制相同的数据。

[11]:
gdf = gdf.set_geometry("centroid")
gdf.plot("area", legend=True)
[11]:
<Axes: >
../_images/getting_started_introduction_20_1.png

我们还可以将两个 GeoSeries 叠加在一起。我们只需使用一个图作为另一个的轴。

[12]:
ax = gdf["geometry"].plot()
gdf["centroid"].plot(ax=ax, color="black")
[12]:
<Axes: >
../_images/getting_started_introduction_22_1.png

现在我们将活动几何形状设置回原始 GeoSeries

[13]:
gdf = gdf.set_geometry("geometry")

用户指南

在用户指南中查看更多关于 映射 的内容。

几何体创建#

我们可以进一步处理几何形状,并基于已有的形状创建新的形状。

凸包#

如果我们对多边形的凸包感兴趣,我们可以访问 GeoDataFrame.convex_hull

[14]:
gdf["convex_hull"] = gdf.convex_hull
[15]:
# saving the first plot as an axis and setting alpha (transparency) to 0.5
ax = gdf["convex_hull"].plot(alpha=0.5)
# passing the first plot and setting linewidth to 0.5
gdf["boundary"].plot(ax=ax, color="white", linewidth=0.5)
[15]:
<Axes: >
../_images/getting_started_introduction_27_1.png

缓冲区#

在其他情况下,我们可能需要使用 GeoDataFrame.buffer() 对几何体进行缓冲。几何方法会自动应用于当前活动几何体,但我们也可以直接对任何 GeoSeries 应用它们。让我们对各个行政区及其质心进行缓冲,并将两者重叠绘制。

[16]:
# buffering the active geometry by 10 000 feet (geometry is already in feet)
gdf["buffered"] = gdf.buffer(10000)

# buffering the centroid geometry by 10 000 feet (geometry is already in feet)
gdf["buffered_centroid"] = gdf["centroid"].buffer(10000)
[17]:
# saving the first plot as an axis and setting alpha (transparency) to 0.5
ax = gdf["buffered"].plot(alpha=0.5)
# passing the first plot as an axis to the second
gdf["buffered_centroid"].plot(ax=ax, color="red", alpha=0.5)
# passing the first plot and setting linewidth to 0.5
gdf["boundary"].plot(ax=ax, color="white", linewidth=0.5)
[17]:
<Axes: >
../_images/getting_started_introduction_30_1.png

用户指南

在用户指南中查看更多关于 几何操作 的信息。

几何关系#

我们还可以询问不同几何图形的空间关系。使用上面的几何图形,我们可以检查哪些缓冲区的区与原始的布鲁克林几何相交,即,距离布鲁克林在10,000英尺以内。

首先,我们获得布鲁克林的一个多边形。

[18]:
brooklyn = gdf.loc["Brooklyn", "geometry"]
brooklyn
[18]:
../_images/getting_started_introduction_32_0.svg

多边形是一个 shapely 几何对象,与 GeoPandas 中使用的其他几何形状相同。

[19]:
type(brooklyn)
[19]:
shapely.geometry.multipolygon.MultiPolygon

然后我们可以检查gdf["buffered"]中的哪些几何图形与之相交。

[20]:
gdf["buffered"].intersects(brooklyn)
[20]:
BoroName
Staten Island     True
Queens            True
Brooklyn          True
Manhattan         True
Bronx            False
dtype: bool

只有布朗克斯(在北部)距离布鲁克林超过 10,000 英尺。其他的都更近并且与我们的多边形相交。

或者,我们可以检查哪些缓冲质心完全位于原始区的多边形内。在这种情况下,两个 GeoSeries 是对齐的,并且检查是在每一行上进行的。

[21]:
gdf["within"] = gdf["buffered_centroid"].within(gdf)
gdf["within"]
[21]:
BoroName
Staten Island     True
Queens            True
Brooklyn         False
Manhattan        False
Bronx            False
Name: within, dtype: bool

我们可以在地图上绘制结果以确认发现。

[22]:
gdf = gdf.set_geometry("buffered_centroid")
# using categorical plot and setting the position of the legend
ax = gdf.plot(
    "within", legend=True, categorical=True, legend_kwds={"loc": "upper left"}
)
# passing the first plot and setting linewidth to 0.5
gdf["boundary"].plot(ax=ax, color="black", linewidth=0.5)
[22]:
<Axes: >
../_images/getting_started_introduction_40_1.png

投影#

每个 GeoSeries 都可以通过 GeoSeries.crs 访问其坐标参考系统 (CRS)。CRS 告诉 GeoPandas 几何体的坐标在地球表面的哪个位置。在某些情况下,CRS 是地理的,这意味着坐标是以经度和纬度表示的。在这些情况下,它的 CRS 是 WGS84,权限代码 EPSG:4326。让我们看看我们纽约区的 GeoDataFrame 的投影。

[23]:
gdf.crs
[23]:
<Projected CRS: EPSG:2263>
Name: NAD83 / New York Long Island (ftUS)
Axis Info [cartesian]:
- X[east]: Easting (US survey foot)
- Y[north]: Northing (US survey foot)
Area of Use:
- name: United States (USA) - New York - counties of Bronx; Kings; Nassau; New York; Queens; Richmond; Suffolk.
- bounds: (-74.26, 40.47, -71.8, 41.3)
Coordinate Operation:
- name: SPCS83 New York Long Island zone (US survey foot)
- method: Lambert Conic Conformal (2SP)
Datum: North American Datum 1983
- Ellipsoid: GRS 1980
- Prime Meridian: Greenwich

几何图形在 EPSG:2263 中,坐标以英尺为单位。我们可以轻松地将 GeoSeries 重新投影到另一个坐标参考系统,如 EPSG:4326,使用 GeoSeries.to_crs()

[24]:
gdf = gdf.set_geometry("geometry")
boroughs_4326 = gdf.to_crs("EPSG:4326")
boroughs_4326.plot()
[24]:
<Axes: >
../_images/getting_started_introduction_44_1.png
[25]:
boroughs_4326.crs
[25]:
<Geographic 2D CRS: EPSG:4326>
Name: WGS 84
Axis Info [ellipsoidal]:
- Lat[north]: Geodetic latitude (degree)
- Lon[east]: Geodetic longitude (degree)
Area of Use:
- name: World.
- bounds: (-180.0, -90.0, 180.0, 90.0)
Datum: World Geodetic System 1984 ensemble
- Ellipsoid: WGS 84
- Prime Meridian: Greenwich

注意到图表坐标轴上的差异。之前我们有 120 000 - 280 000(英尺),现在我们有 40.5 - 40.9(度)。在这种情况下,boroughs_4326 在 WGS84 中具有 "geometry" 列,但所有其他(包括质心等)仍保留在原始 CRS 中。

警告

对于依赖于距离或面积的操作,您始终需要使用投影坐标参考系统(以米、英尺、公里等为单位),而不是地理坐标参考系统(以度为单位)。GeoPandas 操作是平面的,而度数反映的是球体上的位置。因此,使用度数的空间操作可能无法产生正确的结果。例如,gdf.area.sum()(投影坐标参考系统)的结果是 8 429 911 572 ft2,但 boroughs_4326.area.sum()(地理坐标参考系统)的结果是 0.083。

用户指南

在用户指南中查看更多关于 投影 的信息。

接下来做什么?#

使用GeoPandas,我们可以做更多的事情,比到目前为止介绍的内容还要多,从 聚合,到 空间连接,再到 地理编码,以及 更多其他

前往用户指南以了解有关GeoPandas的不同功能的更多信息,查看示例以了解它们如何使用,或查看API参考以获取详细信息。