在geopandas中找到线串的X和Y

发布于 2025-02-07 08:44:40 字数 170 浏览 2 评论 0 原文

我在任何地方都找不到它,所以希望我在这里不会太多。

我有一个polyline shapefile,我正在尝试将“开始和结束”作为新列提取,并且似乎找不到如何使用地理杂货店来做到这一点。

我想最终获得四个新列,startx,starty,endx,Endy,

有人会知道如何获得这个吗?

I have not been able to find this anywhere, so hopefully, I don't get flamed too much here.

I have a polyline shapefile and I'm trying to extract the Start and End XY's as new columns and can't seem to find how to do this with geopandas.

I would like to end up with four new columns, StartX, StartY, EndX, EndY

Would anyone know how to get this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

西瑶 2025-02-14 08:44:40

这是一个 mre 使用100个随机线链接的

import pandas as pd, numpy as np, shapely.geometry, geopandas as gpd
gdf = gpd.GeoDataFrame(
    geometry=[
        shapely.geometry.LineString([tuple(i) for i in np.cumsum(np.random.random(size=(np.random.randint(2, 20), 2)), axis=1)])
        for _ in range(100)
    ],
)

数据帧看起来像这样:

In [2]: gdf
Out[2]:
                                             geometry
0   LINESTRING (0.36610 1.03088, 0.06126 0.29416, ...
1   LINESTRING (0.46164 1.26251, 0.16294 0.45719, ...
2   LINESTRING (0.45853 1.00003, 0.81500 0.92658, ...
3   LINESTRING (0.89925 1.11712, 0.22847 0.97792, ...
4   LINESTRING (0.05748 1.04220, 0.19561 0.86062, ...
..                                                ...
95  LINESTRING (0.62349 0.71080, 0.91981 1.44771, ...
96  LINESTRING (0.18924 0.91123, 0.94212 1.39855, ...
97  LINESTRING (0.79314 1.29408, 0.20462 0.73740, ...
98  LINESTRING (0.07744 0.87544, 0.87101 0.97909, ...
99  LINESTRING (0.31411 0.53442, 0.63755 0.78146, ...

[100 rows x 1 columns]

您可以使用 gdf.boundary 将Linestring的边界作为多点:

In [3]: gdf.boundary
Out[3]:
0     MULTIPOINT (0.36610 1.03088, 0.32418 0.81727)
1     MULTIPOINT (0.46164 1.26251, 0.30703 0.95910)
2     MULTIPOINT (0.45853 1.00003, 0.95016 1.53127)
3     MULTIPOINT (0.89925 1.11712, 0.95730 1.13740)
4     MULTIPOINT (0.05748 1.04220, 0.42954 1.36282)
                          ...
95    MULTIPOINT (0.62349 0.71080, 0.93710 1.55117)
96    MULTIPOINT (0.18924 0.91123, 0.48047 1.08956)
97    MULTIPOINT (0.79314 1.29408, 0.24173 0.56003)
98    MULTIPOINT (0.07744 0.87544, 0.23844 1.23815)
99    MULTIPOINT (0.31411 0.53442, 0.00648 0.76329)
Length: 100, dtype: geometry

然后可以是结合,它将将任何多部分几何形状转换为单个行,然后 unstack 生成的额外索引组以创建新列, 0 1 < /代码>,用于起点和结尾点。每列将包含 shapely.deometry.point 对象:

In [4]: bounds = gdf.geometry.boundary.explode(index_parts=True).unstack()

最后,我们可以直接抓住 x y 值直接的值:

In [5]: gdf['StartX'] = bounds[0].x
   ...: gdf['StartY'] = bounds[0].y
   ...: gdf['EndX'] = bounds[1].x
   ...: gdf['EndY'] = bounds[1].y

这给出了您正在寻找的最终结果:

In [6]: gdf
Out[6]:
                                             geometry    StartX    StartY      EndX      EndY
0   LINESTRING (0.36610 1.03088, 0.06126 0.29416, ...  0.366098  1.030880  0.324176  0.817272
1   LINESTRING (0.46164 1.26251, 0.16294 0.45719, ...  0.461642  1.262513  0.307032  0.959099
2   LINESTRING (0.45853 1.00003, 0.81500 0.92658, ...  0.458530  1.000032  0.950164  1.531267
3   LINESTRING (0.89925 1.11712, 0.22847 0.97792, ...  0.899254  1.117123  0.957299  1.137399
4   LINESTRING (0.05748 1.04220, 0.19561 0.86062, ...  0.057482  1.042202  0.429537  1.362817
..                                                ...       ...       ...       ...       ...
95  LINESTRING (0.62349 0.71080, 0.91981 1.44771, ...  0.623486  0.710795  0.937098  1.551175
96  LINESTRING (0.18924 0.91123, 0.94212 1.39855, ...  0.189237  0.911229  0.480470  1.089565
97  LINESTRING (0.79314 1.29408, 0.20462 0.73740, ...  0.793135  1.294084  0.241726  0.560030
98  LINESTRING (0.07744 0.87544, 0.87101 0.97909, ...  0.077441  0.875441  0.238441  1.238148
99  LINESTRING (0.31411 0.53442, 0.63755 0.78146, ...  0.314106  0.534418  0.006481  0.763287

Here's a MRE with 100 random-length linestrings

import pandas as pd, numpy as np, shapely.geometry, geopandas as gpd
gdf = gpd.GeoDataFrame(
    geometry=[
        shapely.geometry.LineString([tuple(i) for i in np.cumsum(np.random.random(size=(np.random.randint(2, 20), 2)), axis=1)])
        for _ in range(100)
    ],
)

The dataframe looks like this:

In [2]: gdf
Out[2]:
                                             geometry
0   LINESTRING (0.36610 1.03088, 0.06126 0.29416, ...
1   LINESTRING (0.46164 1.26251, 0.16294 0.45719, ...
2   LINESTRING (0.45853 1.00003, 0.81500 0.92658, ...
3   LINESTRING (0.89925 1.11712, 0.22847 0.97792, ...
4   LINESTRING (0.05748 1.04220, 0.19561 0.86062, ...
..                                                ...
95  LINESTRING (0.62349 0.71080, 0.91981 1.44771, ...
96  LINESTRING (0.18924 0.91123, 0.94212 1.39855, ...
97  LINESTRING (0.79314 1.29408, 0.20462 0.73740, ...
98  LINESTRING (0.07744 0.87544, 0.87101 0.97909, ...
99  LINESTRING (0.31411 0.53442, 0.63755 0.78146, ...

[100 rows x 1 columns]

You can use gdf.boundary to get the bounds of the LineString as a MultiPoint:

In [3]: gdf.boundary
Out[3]:
0     MULTIPOINT (0.36610 1.03088, 0.32418 0.81727)
1     MULTIPOINT (0.46164 1.26251, 0.30703 0.95910)
2     MULTIPOINT (0.45853 1.00003, 0.95016 1.53127)
3     MULTIPOINT (0.89925 1.11712, 0.95730 1.13740)
4     MULTIPOINT (0.05748 1.04220, 0.42954 1.36282)
                          ...
95    MULTIPOINT (0.62349 0.71080, 0.93710 1.55117)
96    MULTIPOINT (0.18924 0.91123, 0.48047 1.08956)
97    MULTIPOINT (0.79314 1.29408, 0.24173 0.56003)
98    MULTIPOINT (0.07744 0.87544, 0.23844 1.23815)
99    MULTIPOINT (0.31411 0.53442, 0.00648 0.76329)
Length: 100, dtype: geometry

This can then be combined with explode(), which will convert any multi-part geometry into individual rows, then unstack the resulting extra index groups to create new columns, 0 and 1, for the starting and ending points. Each column will contain shapely.geometry.Point objects:

In [4]: bounds = gdf.geometry.boundary.explode(index_parts=True).unstack()

Finally, we can grab the x and y values for these points directly:

In [5]: gdf['StartX'] = bounds[0].x
   ...: gdf['StartY'] = bounds[0].y
   ...: gdf['EndX'] = bounds[1].x
   ...: gdf['EndY'] = bounds[1].y

This gives the final result you were looking for:

In [6]: gdf
Out[6]:
                                             geometry    StartX    StartY      EndX      EndY
0   LINESTRING (0.36610 1.03088, 0.06126 0.29416, ...  0.366098  1.030880  0.324176  0.817272
1   LINESTRING (0.46164 1.26251, 0.16294 0.45719, ...  0.461642  1.262513  0.307032  0.959099
2   LINESTRING (0.45853 1.00003, 0.81500 0.92658, ...  0.458530  1.000032  0.950164  1.531267
3   LINESTRING (0.89925 1.11712, 0.22847 0.97792, ...  0.899254  1.117123  0.957299  1.137399
4   LINESTRING (0.05748 1.04220, 0.19561 0.86062, ...  0.057482  1.042202  0.429537  1.362817
..                                                ...       ...       ...       ...       ...
95  LINESTRING (0.62349 0.71080, 0.91981 1.44771, ...  0.623486  0.710795  0.937098  1.551175
96  LINESTRING (0.18924 0.91123, 0.94212 1.39855, ...  0.189237  0.911229  0.480470  1.089565
97  LINESTRING (0.79314 1.29408, 0.20462 0.73740, ...  0.793135  1.294084  0.241726  0.560030
98  LINESTRING (0.07744 0.87544, 0.87101 0.97909, ...  0.077441  0.875441  0.238441  1.238148
99  LINESTRING (0.31411 0.53442, 0.63755 0.78146, ...  0.314106  0.534418  0.006481  0.763287
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文