缺失和空几何#
GeoPandas支持,就像在pandas中一样,缺失值(NA或空值)的概念。但对于几何值,还有一个额外的空几何的概念:
空几何 是实际的几何对象,但没有坐标 (因此也没有面积,例如)。例如,它们可以来源于 两个没有重叠的多边形的交集。 标量对象(在访问 GeoSeries 的单个元素时)仍然是 一个 Shapely 几何对象。
缺失的几何形状 是 GeoSeries 中的未知值。它们通常会在操作中传播(例如,在面积或交集的计算中),或在诸如
union_all()
的缩减中被忽略。当访问 GeoSeries 的单个元素时,标量对象是 PythonNone
对象。
警告
从GeoPandas v0.6.0开始,这两个概念的区分更加一致。有关与早期版本相比发生了什么变化的更多细节,请参见下方。
考虑以下示例 GeoSeries,其中包含一个多边形,一个缺失值和一个空的多边形:
In [1]: from shapely.geometry import Polygon
In [2]: s = geopandas.GeoSeries([Polygon([(0, 0), (1, 1), (0, 1)]), None, Polygon([])])
In [3]: s
Out[3]:
0 POLYGON ((0 0, 1 1, 0 1, 0 0))
1 None
2 POLYGON EMPTY
dtype: geometry
在空间操作中,缺失的几何形状通常会传播(在结果中也会缺失),而空几何形状被视为一种几何形状,结果将取决于操作:
In [4]: s.area
Out[4]:
0 0.5
1 NaN
2 0.0
dtype: float64
In [5]: s.union(Polygon([(0, 0), (0, 1), (1, 1), (1, 0)]))
Out[5]:
0 POLYGON ((1 1, 1 0, 0 0, 0 1, 1 1))
1 None
2 MULTIPOLYGON (EMPTY, ((0 0, 0 1, 1 1, 1 0, 0 0)))
dtype: geometry
In [6]: s.intersection(Polygon([(0, 0), (0, 1), (1, 1), (1, 0)]))
Out[6]:
0 POLYGON ((0 0, 0 1, 1 1, 0 0))
1 None
2 POLYGON EMPTY
dtype: geometry
方法 GeoSeries.isna()
将仅检查缺失值,而不检查空几何对象:
In [7]: s.isna()
Out[7]:
0 False
1 True
2 False
dtype: bool
另一方面,如果你想知道哪些值是空几何体, 你可以使用 GeoSeries.is_empty
属性:
In [8]: s.is_empty
Out[8]:
0 False
1 False
2 True
dtype: bool
要获取既不缺失也不为空的实际几何对象,您可以使用两者的组合:
In [9]: s.is_empty | s.isna()
Out[9]:
0 False
1 True
2 True
dtype: bool
In [10]: s[~(s.is_empty | s.isna())]
Out[10]:
0 POLYGON ((0 0, 1 1, 0 1, 0 0))
dtype: geometry
自 GeoPandas v0.6.0 以来的更改#
在GeoPandas v0.6.0中,缺失数据处理进行了重构,并在整个库中变得更加一致。
从历史上看,GeoSeries 中的缺失 (“NA”) 值除了可以由空几何对象表示外,还可以通过标准表示,例如 None
和 np.nan
。至少,在 GeoSeries.isna()
中是这样的,或者当 GeoSeries 在地理空间操作中对齐时也是如此。但是,其他方法如 dropna()
和 fillna()
并没有遵循这种方法,也没有将空几何体视为缺失。
在GeoPandas v0.6.0中,最重要的变化是 GeoSeries.isna()
不再将空值视为缺失:
使用上面的简单示例,旧的行为将空值作为“缺失”的几何体处理为“缺失”:
>>> s 0 POLYGON ((0 0, 1 1, 0 1, 0 0)) 1 None 2 GEOMETRYCOLLECTION EMPTY dtype: object >>> s.isna() 0 False 1 True 2 True dtype: bool
从 GeoPandas v0.6.0 开始,它现在只会将实际缺失的值视为缺失:
In [11]: s.isna() Out[11]: 0 False 1 True 2 False dtype: bool
现在,当在具有空几何的 GeoSeries 上调用
isna()
时,会引发警告,以提醒用户已更改的行为,并指示如何解决此问题。
此外,GeoSeries.align()
的行为改变为使用缺失值而不是空几何体来填充不匹配的索引。考虑以下小示例:
In [12]: from shapely.geometry import Point
In [13]: s1 = geopandas.GeoSeries([Point(0, 0), Point(1, 1)], index=[0, 1])
In [14]: s2 = geopandas.GeoSeries([Point(1, 1), Point(2, 2)], index=[1, 2])
In [15]: s1
Out[15]:
0 POINT (0 0)
1 POINT (1 1)
dtype: geometry
In [16]: s2
Out[16]:
1 POINT (1 1)
2 POINT (2 2)
dtype: geometry
之前,
align
方法会使用空几何来填充值:>>> s1_aligned, s2_aligned = s1.align(s2) >>> s1_aligned 0 POINT (0 0) 1 POINT (1 1) 2 GEOMETRYCOLLECTION EMPTY dtype: object >>> s2_aligned 0 GEOMETRYCOLLECTION EMPTY 1 POINT (1 1) 2 POINT (2 2) dtype: object
当对不对齐的 GeoSeries 对象执行空间操作时,将在后台使用此方法:
>>> s1.intersection(s2) 0 GEOMETRYCOLLECTION EMPTY 1 POINT (1 1) 2 GEOMETRYCOLLECTION EMPTY dtype: object
从 GeoPandas v0.6.0 开始,
GeoSeries.align()
将使用缺失值来填充未对齐的索引,以保持与 pandas 的行为一致:在 [17]: s1_aligned, s2_aligned = s1.align(s2) 在 [18]: s1_aligned 输出 [18]: 0 POINT (0 0) 1 POINT (1 1) 2 None dtype: geometry 在 [19]: s2_aligned 输出 [19]: 0 None 1 POINT (1 1) 2 POINT (2 2) dtype: geometry
这导致空间操作也将使用缺失值而不是空几何,这可能会根据空间操作的不同而表现出不同的行为:
在 [20]: s1.intersection(s2) 输出 [20]: 0 None 1 POINT (1 1) 2 None dtype: geometry