Konversikan panda DataFrame menjadi GeoDataFrame

42

Ini sepertinya pertanyaan yang cukup sederhana, tapi saya tidak tahu cara mengubah DataFrame panda menjadi GeoDataFrame untuk penggabungan spasial.

Berikut adalah contoh bagaimana data saya terlihat menggunakan 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

Bahkan, kerangka data ini dibuat dari CSV jadi jika lebih mudah untuk membaca CSV secara langsung sebagai GeoDataFrame juga tidak masalah.

atkat12
sumber
1
gunakan GeoPandas
gen

Jawaban:

78

Konversikan konten DataFrame (mis. LatDan Lonkolom) menjadi geometri Shapely yang sesuai terlebih dahulu dan kemudian menggunakannya bersama dengan DataFrame asli untuk membuat 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)

Hasil:

    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)

Karena geometri sering kali datang dalam format WKT, saya pikir saya akan menyertakan contoh untuk kasus itu juga:

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)
Martin Valgur
sumber
Terima kasih lagi! Itu jauh lebih sederhana dan berjalan sangat cepat - jauh lebih baik daripada mengulangi setiap baris df di n = 500.000 saya :)
atkat12
6
Astaga, terima kasih! Saya memeriksa jawaban ini seperti setiap 2 hari :)
Owen
1
Anda akan berpikir ini akan menjadi entri pertama dalam dokumentasi!
Dominik
+1 untuk shapely.wkt. Butuh beberapa saat untuk memikirkan ini!
StefanK
14

Satu kalimat! Ditambah beberapa petunjuk kinerja untuk orang-orang big-data.

Diberi a pandas.DataFrameyang memiliki x Longitude dan y Latitude seperti:

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

Mari kita konversikan pandas.DataFramemenjadi geopandas.GeoDataFrame:

Impor perpustakaan dan speedup rupawan :

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

Kode + waktu tolok ukur pada dataset uji yang saya miliki:

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

Penggunaannya pandas.applysecara mengejutkan lebih lambat, tetapi mungkin lebih cocok untuk beberapa alur kerja lainnya (misalnya pada kumpulan data yang lebih besar menggunakan pustaka dask):

Kredit untuk:

Beberapa referensi Work-In-Progress (per 2017) untuk menangani daskkumpulan data besar :

weiji14
sumber
Terima kasih atas perbandingannya, memang versi
zipnya