如何将 GeoDataFrame 存储到 NetCDF 文件
Posted
技术标签:
【中文标题】如何将 GeoDataFrame 存储到 NetCDF 文件【英文标题】:How to store GeoDataFrame to NetCDF file 【发布时间】:2022-01-07 03:33:09 【问题描述】:我想将 GeoDataFrame 保存为 NetCDF 文件。然后,我可以稍后将它与另一个 NetCDF 文件结合起来。
但是,保存从 GeoDataFrame 转换的数据集时会出错。这是一个简单的代码和错误信息:
import geopandas
world = geopandas.read_file(geopandas.datasets.get_path('naturalearth_lowres'))
ds = world.to_xarray()
ds.to_netcdf('test.nc')
错误:
ds.to_netcdf('test.nc')
File "/public/home/zhangxin/new/miniconda3/envs/knmi_arctic_new/lib/python3.8/site-packages/xarray/core/dataset.py", line 1902, in to_netcdf
return to_netcdf(
File "/public/home/zhangxin/new/miniconda3/envs/knmi_arctic_new/lib/python3.8/site-packages/xarray/backends/api.py", line 1072, in to_netcdf
dump_to_store(
File "/public/home/zhangxin/new/miniconda3/envs/knmi_arctic_new/lib/python3.8/site-packages/xarray/backends/api.py", line 1119, in dump_to_store
store.store(variables, attrs, check_encoding, writer, unlimited_dims=unlimited_dims)
File "/public/home/zhangxin/new/miniconda3/envs/knmi_arctic_new/lib/python3.8/site-packages/xarray/backends/common.py", line 261, in store
variables, attributes = self.encode(variables, attributes)
File "/public/home/zhangxin/new/miniconda3/envs/knmi_arctic_new/lib/python3.8/site-packages/xarray/backends/common.py", line 350, in encode
variables, attributes = cf_encoder(variables, attributes)
File "/public/home/zhangxin/new/miniconda3/envs/knmi_arctic_new/lib/python3.8/site-packages/xarray/conventions.py", line 855, in cf_encoder
new_vars = k: encode_cf_variable(v, name=k) for k, v in variables.items()
File "/public/home/zhangxin/new/miniconda3/envs/knmi_arctic_new/lib/python3.8/site-packages/xarray/conventions.py", line 855, in <dictcomp>
new_vars = k: encode_cf_variable(v, name=k) for k, v in variables.items()
File "/public/home/zhangxin/new/miniconda3/envs/knmi_arctic_new/lib/python3.8/site-packages/xarray/conventions.py", line 275, in encode_cf_variable
var = ensure_dtype_not_object(var, name=name)
File "/public/home/zhangxin/new/miniconda3/envs/knmi_arctic_new/lib/python3.8/site-packages/xarray/conventions.py", line 233, in ensure_dtype_not_object
data = _copy_with_dtype(data, dtype=_infer_dtype(data, name))
File "/public/home/zhangxin/new/miniconda3/envs/knmi_arctic_new/lib/python3.8/site-packages/xarray/conventions.py", line 167, in _infer_dtype
raise ValueError(
ValueError: unable to infer dtype on variable 'geometry'; xarray cannot serialize arbitrary Python objects
在NC文件中不能保存MULTIPOLYGON
或POLYGON
吗?如果您有任何建议,我将不胜感激。
【问题讨论】:
@RobRaymond 的 answer 确实将形状的坐标转换为 netCDF,但现在您将拥有一个巨大的 netcdf,其中包含整个自然地球 shapefile 中每个点的单元格,以及所有元数据关于每个点重复的每个形状,您已经失去了使它们成为多边形/多面体的点之间的实际关系。你为什么要这样做? GIS 原生存储格式(例如 shapefile 或 GeoParquet)是否不合适? @MichaelDelgado 嗨,因为我有 NetCDF 文件,每个文件都有一些几何信息。我想将几何图形保存在里面会很方便,而不是配对geojson或shapefile。 知道了。是的,我不会在该答案中使用该方法,因为数据将不再按区域索引。如果您确实需要这样做,您可以将形状转换为字符串或压缩格式,例如WKB。不过,这将涉及损失/压缩。我的建议是只指向元数据中的 shapefile 路径并在使用时读取它。 【参考方案1】:您可以将几何扩展为纬度/经度序列。
import geopandas
import shapely.geometry
world = geopandas.read_file(geopandas.datasets.get_path("naturalearth_lowres"))
ds = world.drop(columns="geometry").join(
world["geometry"]
.apply(lambda g: [g] if isinstance(g, shapely.geometry.Polygon) else g.geoms)
.explode()
.apply(lambda p: p.exterior.coords)
.explode()
.apply(pd.Series)
.rename(columns=0: "lat", 1: "lon")
).to_xarray()
ds.to_netcdf('test.nc')
【讨论】:
好方法!顺便说一句,您似乎犯了一个简单的错误。应该是0: "lon", 1: "lat"
。
我经常把它们弄错,需要修复:-)以上是关于如何将 GeoDataFrame 存储到 NetCDF 文件的主要内容,如果未能解决你的问题,请参考以下文章
GeoPandas 笔记: GeoDataFrame.plot()
Python中的GeoPandas和GeoDataFrame