xarray系列|数据处理和分析小技巧

2022-09-23 14:10:40 浏览数 (1)

拖了很长时间的技巧总结,再不写的话我可能也要忘了。趁着这几天在处理数据,赶紧补上,全文共近2500字。

以下内容没有过多代码,对于很新的新手可能不是很友好,但如果你已经接触 xarray 一段时间,对其数据结构和常用函数有所了解,相信会对你有帮助的。

数据读写

简单说一下数据读写的问题,这里说的主要是批量文件读写。因为我主要接触的是nc格式,以nc数据为主:

在利用 xr.open_mfdataset 批量读取文件时,建议设置 engine=h5netcdf,比默认的 engine=netcdf4 要更快;

利用 xr.open_mfdataset 批量读取文件时可以设置 parallel=True 能显著改善文件读取效率;注意chunks 不要随便设置,整不好会降低读取的速度

xr.open_mfdataset 函数有 preprocess 参数,这个参数主要是在读取文件之前先进行一定的处理,如果批量操作涉及到维度合并等操作时比较有用,比如要合并的维度不是坐标,可能会出现以下错误,需要先将合并的维度设置为坐标

代码语言:javascript复制
ValueError: Could not find any dimension coordinates to use to order the datasets for concatenation

xr.open_mfdataset 目前还不是很稳定,有时性能可能会降低,如果发现读取时间特别长,可以先测试单文件读取看是否正常;

xr.save_mfdataset 可以进行nc文件的批量写入操作,但是使用时需要注意,后面单独推一下批量写nc文件;

如果不是必须要用nc和grib等格式的话,可以尝试一下 zarr格式,在文件的读取方面非常方便,而且效率要更高,可以实现文件的并行读写和增量写操作;

注意:目前没有类似 xr.open_mfdataset 的函数批量读取 zarr 格式文件,如果读取两个不同的 zarr 格式文件,想要合并时,可能会出现 chunk 不一致的问题,这时候可以通过 .chunk 方法重新设置 chunk 大小进行合并,比如:

代码语言:javascript复制
zarr3 = (xr.concat([zarr1, zarr2], dim='time')
      .chunk({'time': 10, 'lon': 100, 'lat': 100}))

文件写入时为了防止文件太大,可以通过 encoding 参数对变量进行压缩和数据类型调整,比如通过 add_offsetscales 调整变量。

数据处理

数据处理的内容比较多,这里主要以数据的索引、筛选为主,关于数据的插值和统计计算以后再说(又拖了一次,哈哈)

第一个要说的是后台留言询问的,如果从daily的nc文件中抽取某些年份1-4月的数据?

我的答案还是按照时间索引就行了。这里给上代码吧:注意 ds 的坐标一定要有 time维度,名称不一定是 time,但一定要有时间格式的坐标才行。

代码语言:javascript复制
ds.sel(time=ds.time.dt.month.isin([1, 2, 3, 4]))

其实xarray 在时间序列处理方面的功能非常强大,而且内置了很多语法糖,比如按照季节筛选和计算,这些官方文档说的都非常详细,以前也说到过 xarray系列|教你更高效的进行数据处理和分析。建议遇到问题的时候先看官方文档。

站点数据提取的问题,这是要注意的一点。由于xarray的索引的特点,在使用 .isel.sel 等函数索引时,所给定的参数的类型应该是 xarra.DataArray,如果是其它参数的得到的可能就不是索引的站点数据,这个之前也提到过 xarray系列|WRF模式前处理和后处理

善用 .sel.isel.where 等索引函数能够有效改善数据处理效率。注意在使用的时候想清楚要实现的效果。

刚好最近处理数据也要用到 mask,这里顺带提一下。xarraymask 还是非常方便的,同时结合 regionmaskgeopandas几乎可以实现任何想要的功能。

比如利用shapefile文件进行mask筛选数据,也可以任意指定形状和区域进行筛选。

进行插值和统计计算时建议使用 xr.apply_ufuncmap_blocks 函数,可以显著改善处理效率,结合 dask 的话简直如有神助。

这几天在处理数据时就碰到了此类问题。用 pandas 处理效率太低,就算用了 modinswifterpandarallel 这些傻瓜式一键加速工具也不能达到效果,猜测可能是在处理数据时有 xarray 的数据对象分配导致。然后转到 xarray,效果也差不多,最后结合 dask,实现了几十倍的效率提升,由原先的近40小时降低到2小时左右。

以下是一点经验之谈:如果处理数据时只涉及到 pandas 的数据结构,比如 DataFrameSeries等,可以直接用 pandarallel 等傻瓜式一键并行,效率提升非常显著,亲测有效。注意如果涉及到其它库的数据对象时可能会失效

涉及到大量的数据处理时,可以结合 xarraydask 改善效率,但是 dask 的学习成本稍高一些。

有效结合 xarraypandas 能够更好的进行数据处理和分析,比如在不规则数据索引时。不要想单独利用某一个工具实现所有功能。

其中涉及到的一些点展开说的话篇幅太大,以后单独细说。如果你遇到了一些问题的话,也可以评论留言,我收集一下,回头可以放到菜单栏中实时更新。

一不小心就写了这么多,很多经验都是细节问题。其实数据处理和分析过程中会碰到很多问题,可以直接 google 搜索,而不是百度之类的搜索引擎。因为 google 给出的搜索结果更简单直接,节省时间。

编程问题建议直接在 stackoverflow 搜索,面向 stackoverflow 编程不是瞎说的

—END—

0 人点赞