Biến GeoDataFrame của tọa độ x, y thành Linestrings bằng GROUPBY?


8

Tôi có một khung dữ liệu gồm các tọa độ X, Y đại diện cho các điểm dọc theo các đường dẫn được thực hiện bởi một số thực thể khác nhau. Dữ liệu giả ở đây, nhưng nó có dạng đại khái:

entity_id   lat   lon   time

1001        34.5  14.2  4:55 pm
1001        34.7  14.5  4:58 pm
1001        35.0  14.6  5.03 pm

1002        27.1  19.2  2:01 pm
1002        27.4  19.3  2:08 pm
1002        27.4  19.9  2:09 pm

Những gì tôi muốn làm là nhóm các điểm này theo entity_id, và sau đó sắp xếp các điểm theo tuần tự để tạo một LineStringđối tượng cho mỗi điểm entity_id. Đầu ra sẽ là một vài dòng / đường dẫn, với mỗi đường dẫn tương ứng với một entity_id.

Tôi có thể làm điều này bằng cách lặp qua từng entity_idđiểm entity_idvà sử dụng các hướng dẫn được cung cấp ở đây , nhưng có cách nào nhanh hơn / hiệu quả hơn để làm điều này thúc đẩy GeoPandas hoặc Shapely, có lẽ với groupby?

Câu trả lời:


16

Tôi nghĩ rằng tôi đã tìm thấy một giải pháp tạm thời, mà tôi đang đăng trong trường hợp nó hữu ích cho bất kỳ ai:

import pandas as pd
import numpy as np
from geopandas import GeoDataFrame
from shapely.geometry import Point, LineString

# Zip the coordinates into a point object and convert to a GeoDataFrame
geometry = [Point(xy) for xy in zip(df.lon, df.lat)]
df = GeoDataFrame(df, geometry=geometry)

# Aggregate these points with the GroupBy
df = df.groupby(['entity_id'])['geometry'].apply(lambda x: LineString(x.tolist()))
df = GeoDataFrame(df, geometry='geometry')

Lưu ý rằng nếu bạn có quỹ đạo một điểm trong dữ liệu của mình, bạn sẽ phải loại bỏ những điểm đầu tiên này hoặc LineString sẽ đưa ra lỗi.

Đâyđây bài là hữu ích trong việc viết các chức năng groupby.


Cập nhật : Nếu bạn không loại bỏ điểm duy nhất, bạn cũng có thể sử dụng câu có điều kiện như:

 df = df.groupby(['entity_id'])['geometry'].apply(lambda x: LineString(x.tolist()) if x.size > 1 else x.tolist())

Thật tuyệt vời!
Ufos

Trong trường hợp bạn chỉ muốn tập dữ liệu được nhóm và giữ ID làm cột, điều này sẽ giúp:df.groupby('entity_id', as_index=False).agg({'geometry': lambda x: ...})
Ufos
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.