将熊猫数据框转换为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
基因

Answers:


78

首先将DataFrame的内容(例如LatLon列)转换为适当的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 2015年

6
天哪,谢谢!我每2天检查一次此答案:)
Owen

1
您会认为这将是文档中的第一项!
多米尼克

为shapely.wkt +1。我花了一段时间才弄清楚!
StefanK

14

一线!再加上一些针对大数据人员的性能指标。

给定一个pandas.DataFrame具有x经度和y纬度的,如下所示:

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版本速度更快
MCMZL
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.