GROUPBYを使用してx、y座標のGeoDataFrameを折れ線に変換しますか?


8

複数の異なるエンティティがたどるパスに沿ったポイントを表すX、Y座標のデータフレームがあります。ここでは疑似データですが、おおよその形式です:

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

私がしたいことはentity_id、これらのポイントをでグループ化し、ポイントを順番に並べて、LineStringそれぞれのオブジェクトを作成することですentity_id。出力は、それぞれがに対応する複数のライン/パスになりますentity_id

これを行うにはentity_id、各ポイントをループentity_idし、ここに記載さている手順を使用しますが、GeoPandasまたはShapelyを利用してこれを行うためのより高速で効率的な方法はありgroupbyますか?

回答:


16

私は暫定的な解決策を見つけたと思います。誰かのために役立つ場合に備えて投稿しています。

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')

データに単一ポイントの軌跡がある場合は、最初にこれらを破棄する必要があります。そうしないと、LineStringがエラーをスローします。

この投稿とこの投稿は、GroupBy関数の作成に役立ちました。


更新:単一のポイントを破棄しなかった場合は、次のような条件文も使用できます。

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

すごい!
Ufos 2018

あなたが唯一のグループ化されたデータセットをしたいと列としてIDを維持する場合には、これは役立つはずです:df.groupby('entity_id', as_index=False).agg({'geometry': lambda x: ...})
UFOの
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.