缺少的几何图形和空的几何图形#

就像在熊猫中一样,GeoPandas支持缺失值(NA或空值)的概念。但对于几何值,我们有一个额外的空几何概念:

  • 空几何图形 是实际的几何体对象,但没有坐标(因此也没有面积)。例如,它们可以源于取两个没有重叠的多边形的交集。标量对象(当访问GeoSeries的单个元素时)仍然是形状良好的几何体对象。

  • 缺少的几何图形 是GeoSeries中的未知值。它们通常在运算中传播(例如,在面积或交叉点的计算中),或在减去中忽略,例如 unary_union 。标量对象(在访问GeoSeries的单个元素时)是Python None 对象。

警告

从GeoPandas v0.6.0开始,这两个概念更加一致地分开。看见 below 有关与早期版本相比有哪些变化的更多详细信息,请参阅。

考虑以下示例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.000000000 0.000000000, 1.000000000...
1                                                 None
2                             GEOMETRYCOLLECTION 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.000000000 1.000000000, 1.000000000...
1                                                 None
2    POLYGON ((0.000000000 0.000000000, 0.000000000...
dtype: geometry

In [6]: s.intersection(Polygon([(0, 0), (0, 1), (1, 1), (1, 0)]))
Out[6]: 
0    POLYGON ((0.000000000 0.000000000, 0.000000000...
1                                                 None
2                             GEOMETRYCOLLECTION 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.000000000 0.000000000, 1.000000000...
dtype: geometry

GeoPandas v0.6.0以来的更改#

在GeoPandas v0.6.0中,对缺失数据的处理进行了重构,使其在整个库中更加一致。

从历史上看,GeoSeries中缺失的(NA)值可以由空几何对象来表示,此外还可以使用标准表示,例如 Nonenp.nan 。至少,情况是这样的。 GeoSeries.isna() 或者当地理系列在地理空间操作中对齐时。但是,其他方法,如 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
    

    就目前而言,当 isna() 在具有空几何图形的GeoSeries上调用,则会引发警告,警告用户行为已更改,并指示如何解决此问题。

此外,还有一种行为 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.000000000 0.000000000)
1    POINT (1.000000000 1.000000000)
dtype: geometry

In [16]: s2
Out[16]: 
1    POINT (1.000000000 1.000000000)
2    POINT (2.000000000 2.000000000)
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() 将使用缺失值来填充非对齐索引,以与熊猫的行为一致:

    In [17]: s1_aligned, s2_aligned = s1.align(s2)
    
    In [18]: s1_aligned
    Out[18]: 
    0    POINT (0.000000000 0.000000000)
    1    POINT (1.000000000 1.000000000)
    2                               None
    dtype: geometry
    
    In [19]: s2_aligned
    Out[19]: 
    0                               None
    1    POINT (1.000000000 1.000000000)
    2    POINT (2.000000000 2.000000000)
    dtype: geometry
    

    这样做的结果是,空间操作也将使用缺失的值,而不是空几何图形,空几何图形可能具有不同的行为,具体取决于空间操作:

    In [20]: s1.intersection(s2)
    Out[20]: 
    0                               None
    1    POINT (1.000000000 1.000000000)
    2                               None
    dtype: geometry