两个GeoSeries的索引不同 - 理解索引

7
我正在使用GeoPandas,有两个具有相同坐标参照系CRSGeoDataframes。其中一个包含了一个多边形geometry列,另一个包含了一个点geometry列。我想检查哪些点在多边形内部。
我尝试了一种简单的方法:
shape.contains(points)

这让我感到

>  The indices of the two GeoSeries are different

我不理解这个信息。当我查看文档时,它说:

我们还可以逐行检查两个GeoSeries之间的差异。上面的GeoSeries具有不同的索引。我们可以基于索引值对两个GeoSeries进行对齐,并使用align=True比较具有相同索引的元素,或者忽略索引并根据其匹配顺序比较元素,使用align=False:

这些索引是什么?为什么要相互检查而不是geometry columns? 在网上阅读到,我必须将我的几何对象转换为shapely几何对象。但使用GeoPandas的整个意义不就是可以对数据执行地理操作吗?

我对此感到困惑。如何检查shape中的geometries是否包含points中的任何一个geometries

3个回答

4
你所描述的实际上是一种空间连接。下面的例子使用英国城市的经纬度构建点,并查找该城市所在的行政区域多边形。这是一次NxM比较。
import pandas as pd
import numpy as np
import geopandas as gpd
import shapely.geometry
import requests

# source some points and polygons
# fmt: off
dfp = pd.read_html("https://www.latlong.net/category/cities-235-15.html")[0]
dfp = gpd.GeoDataFrame(dfp, geometry=dfp.loc[:,["Longitude", "Latitude",]].apply(shapely.geometry.Point, axis=1))
res = requests.get("https://opendata.arcgis.com/datasets/69dc11c7386943b4ad8893c45648b1e1_0.geojson")
df_poly = gpd.GeoDataFrame.from_features(res.json())
# fmt: on

gpd.sjoin(dfp, df_poly)

是的,这正是我要找的。直觉上,我会选择 contains()。有没有关于如何计算多边形中有多少点并将该数字附加到多边形数据框中每一行的提示?类似于 gpd.sjoin(dfp, df_poly).groupBy('OBJECTID').count() 这样的东西。 - four-eyes
df_poly.merge(gpd.sjoin(dfp, df_poly).groupby("index_right").size().rename("points"), left_index=True, right_index=True, how="left") 将把点的数量放回多边形地理数据框中。 - Rob Raymond

1

这些指数是什么?

简单来说,索引是 pandas.DataFrame 的行名称或 pandas.Series 的条目。使用索引对齐在数据部分重叠时非常有用,考虑以下示例:假设您有来自两个传感器的每日数据,但第二个传感器稍后才开启,则可以准备如下的 pandas.DataFrame

import pandas as pd
s1 = pd.Series({'day1':100,'day2':110,'day3':105,'day4':120,'day5':110})
s2 = pd.Series({'day3':100,'day4':105,'day5':100})
df = pd.DataFrame({'sensor1':s1,'sensor2':s2})
print(df)

输出

      sensor1  sensor2
day1      100      NaN
day2      110      NaN
day3      105    100.0
day4      120    105.0
day5      110    100.0

请注意,对于sensor2day1day2的值被插入了NaN(表示未知值)。

感谢解释。这意味着当我得到“两个GeoSeries的索引不同”时,这两个“数据框架”长度不同?这至少是当我尝试使用shape.contains(points, align = True)时,GeoPandas告诉我的内容。 - four-eyes
@Stophface 如果长度不同,它们将是不同的,但对于相同长度的数据框,它们也可能不同。想象一下,你有来自传感器1的第1天、第2天、第3天的数据,以及来自传感器2的第2天、第3天、第4天的数据 - 长度相等,但索引不同。 - Daweo

0

contains操作并不进行完整的NxM比较。它可以检查哪些多边形包含单个点。或者如果您提供了两个系列,它将检查第一个多边形是否包含第一个点,第二个多边形是否包含第二个点,依此类推。

您遇到的错误是geopandas尝试使用第二个选项,但是点和多边形不对齐,因此无法进行逐元素比较。

听起来您想要进行所有多边形乘以所有点的完整比较。您可以通过迭代所有点来实现:

point_series = gpd.GeoSeries([Point(1, 2), Point(2, 1)])

polygon_series = gpd.GeoSeries(
    [
        Polygon([(0, 0), (0, 3), (2, 3), (2, 0), (0, 0)]),
        Polygon([(0, 0), (0, 2), (3, 2), (3, 0), (0, 0)]),
    ]
)

pd.concat([polygon_series.contains(point) for point in point_series], axis=1)

输出:

    0       1
0   True    False
1   False   True

1
是的,我确实想填充NxM比较。在多边形数据帧中有各种多边形,在点数据帧中有几个点。当我运行您的代码pd.concat([polygons['geometry'].contains(points['geometry']) for point in points['geometry']], axis = 1)时,我仍然得到The indices of the two GeoSeries are different。但不仅一次,而是每次迭代Python都会出现这种情况。 - four-eyes
你分享的代码片段使用了.contains(points['geometry'])而不是.contains(point),这就解释了错误的原因。 - Swier

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接