Pandas DataFrameをGeoDataFrameに変換する


42

これは十分に簡単な質問のように思えますが、空間結合のためにパンダのDataFrameをGeoDataFrameに変換する方法がわかりません。

以下は私のデータがどのように見えるかの例ですdf.head()

    Date/Time           Lat       Lon       ID
0   4/1/2014 0:11:00    40.7690   -73.9549  140
1   4/1/2014 0:17:00    40.7267   -74.0345  NaN

実際、このデータフレームはCSVから作成されているため、CSVをGeoDataFrameとして直接読み込む方が簡単であれば、それでも問題ありません。


1
使用GeoPandas
遺伝子

回答:


78

最初にDataFrameのコンテンツ(LatおよびLon列)を適切なShapelyジオメトリに変換し、次にそれらを元のDataFrameと共に使用してGeoDataFrameを作成します。

from geopandas import GeoDataFrame
from shapely.geometry import Point

geometry = [Point(xy) for xy in zip(df.Lon, df.Lat)]
df = df.drop(['Lon', 'Lat'], axis=1)
crs = {'init': 'epsg:4326'}
gdf = GeoDataFrame(df, crs=crs, geometry=geometry)

結果:

    Date/Time           ID      geometry
0   4/1/2014 0:11:00    140     POINT (-73.95489999999999 40.769)
1   4/1/2014 0:17:00    NaN     POINT (-74.03449999999999 40.7267)

多くの場合、ジオメトリはWKT形式で提供されるため、その場合の例も含めると思いました。

import geopandas as gpd
import shapely.wkt

geometry = df['wktcolumn'].map(shapely.wkt.loads)
df = df.drop('wktcolumn', axis=1)
crs = {'init': 'epsg:4326'}
gdf = gpd.GeoDataFrame(df, crs=crs, geometry=geometry)

再度、感謝します!それははるかに簡単で非常に高速です-私のn = 500,000でdfのすべての行を反復するよりもはるかに優れています:)
atkat12

6
まあ、ありがとう!私はこの答えを2日ごとに確認します:)
オーウェン

1
これがドキュメントの最初のエントリになると思います!
ドミニク

shapely.wktの場合は+1。これを理解するのに時間がかかりました!
StefanK

14

ワンライナー!加えて、ビッグデータの人々のためのいくつかのパフォーマンスポインター。

次のpandas.DataFrameようなx経度とy緯度を持つa を考えると:

df.head()
x   y
0   229.617902  -73.133816
1   229.611157  -73.141299
2   229.609825  -73.142795
3   229.607159  -73.145782
4   229.605825  -73.147274

レッツ・変換pandas.DataFramegeopandas.GeoDataFrame次のように:

ライブラリのインポートと見栄えの高速化

import geopandas as gpd
import shapely
shapely.speedups.enable() # enabled by default from version 1.6.0

私が横たわっているテストデータセットのコード+ベンチマーク時間:

#Martin's original version:
#%timeit 1.87 s ± 7.03 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
gdf = gpd.GeoDataFrame(df.drop(['x', 'y'], axis=1),
                                crs={'init': 'epsg:4326'},
                                geometry=[shapely.geometry.Point(xy) for xy in zip(df.x, df.y)])



#Pandas apply method
#%timeit 8.59 s ± 60.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
gdf = gpd.GeoDataFrame(df.drop(['x', 'y'], axis=1),
                       crs={'init': 'epsg:4326'},
                       geometry=df.apply(lambda row: shapely.geometry.Point((row.x, row.y)), axis=1))

使用pandas.applyは驚くほど遅くなりますが、他のいくつかのワークフロー(たとえば、daskライブラリを使用するより大きなデータセット)に適している場合があります。

クレジット:

大きなdaskデータセットを処理するためのいくつかの進行中の参照(2017年現在):


比較していただきありがとうございます。実際、zipバージョンの方が
はるかに
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.