如何将带geometry列的R DataFrame转换为Pandas/GeoPandas DataFrame?
带Geometry列的R SF对象转Pandas/GeoPandas DataFrame解决方案
问题背景
通过rpy2调用R的osrm库生成带geometry列的SF(Simple Feature)对象后,使用ro.conversion.rpy2py直接转换得到空的DataFrame,需要将该对象转换为Pandas或GeoPandas DataFrame。
原执行代码
from rpy2 import robjects import rpy2.robjects as ro robjects.r(''' library(osrm) iso <- osrmIsochrone(loc = c(12.0878, 55.6419), breaks = seq(from = 0, to = 60, length.out = 2), res = 50) print(iso)''')
R输出结果
Simple feature collection with 1 feature and 3 fields Geometry type: MULTIPOLYGON Dimension: XY Bounding box: xmin: 11.10805 ymin: 55.02879 xmax: 13.14378 ymax: 56.08983 Geodetic CRS: WGS 84 id isomin isomax geometry 1 1 0 60 MULTIPOLYGON (((12.54979 56...
失败的转换代码
r_mat = robjects.globalenv['iso'] pd_dt = ro.conversion.rpy2py(r_mat) pd_dt
转换后输出
R/rpy2 DataFrame (1 x 4) id isomin isomax geometry ... ... ... ...
解决方案
原因说明
R中的iso是SF(Simple Feature)对象,并非普通R DataFrame,rpy2默认转换器无法识别SF特有的geometry列,导致转换不完整。以下提供两种可行方法:
方法一:手动转换为GeoPandas DataFrame
通过提取非geometry列到Pandas,再将R的geometry转换为Shapely对象,最终构建GeoDataFrame:
from rpy2 import robjects from rpy2.robjects import pandas2ri import geopandas as gpd from shapely.wkt import loads # 激活rpy2与Pandas的转换支持 pandas2ri.activate() # 获取R环境中的SF对象 r_iso = robjects.globalenv['iso'] # 提取非geometry列转为Pandas DataFrame df = pandas2ri.rpy2py(r_iso.drop('geometry')) # 定义函数:将R的SF geometry转为Shapely对象 def r_geom_to_shapely(r_geom_col): # 用R的st_as_text将geometry转为WKT格式 r_wkt = robjects.r['st_as_text'](r_geom_col) return loads(str(r_wkt[0])) # 处理geometry列并添加到DataFrame df['geometry'] = [r_geom_to_shapely(r_iso.rx2('geometry')[i]) for i in range(r_iso.nrow)] # 转换为GeoPandas DataFrame,指定CRS(与R输出一致为WGS84) gdf = gpd.GeoDataFrame(df, crs="EPSG:4326") # 查看结果 print(gdf)
方法二:通过GeoJSON中转
利用R的sf包将对象导出为GeoJSON,再用GeoPandas读取:
from rpy2 import robjects from rpy2.robjects.packages import importr import geopandas as gpd # 导入R的sf包 sf = importr('sf') # 获取R环境中的SF对象 r_iso = robjects.globalenv['iso'] # 将SF对象导出为临时GeoJSON文件 sf.st_write(r_iso, 'temp_isochrone.geojson', driver='GeoJSON') # 用GeoPandas读取GeoJSON文件 gdf = gpd.read_file('temp_isochrone.geojson') # 查看结果 print(gdf)
内容的提问来源于stack exchange,提问作者data en
相关产品推荐
相关产品推荐

