Конвертируйте DataFrame для панд в GeoDataFrame

42

Это кажется довольно простым вопросом, но я не могу понять, как преобразовать DataFrame pandas в 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, это тоже хорошо.

atkat12
источник
1
использовать GeoPandas
ген

Ответы:

78

Преобразовать содержимое DataFrame (например Latи Lonстолбцы) в соответствующие стройных геометрии первым , а затем использовать их вместе с оригинальным 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)
Мартин Валгур
источник
Еще раз спасибо! Это намного проще и работает очень быстро - намного лучше, чем перебирать каждую строку df при моем n = 500 000 :)
atkat12
6
Гоша, спасибо! Я проверяю этот ответ, как каждые 2 дня :)
Оуэн
1
можно подумать, что это будет первая запись в документации!
Доминик
+1 для стройных.wkt. Мне понадобилось время, чтобы понять это!
StefanK
14

Однострочники! Плюс несколько указателей производительности для людей с большими данными.

Учитывая, pandas.DataFrameчто имеет х Долгота и у Широта, как это:

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.DataFrameв a geopandas.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):

Кредиты для:

Некоторые ссылки на Work-In-Progress (по состоянию на 2017 год) для обработки больших daskнаборов данных:

weiji14
источник
Спасибо за сравнение, действительно версия почтового индекса намного быстрее
MCMZL