以下文章来源于深雨露 ,作者嵊雨饧
封图:Photo by Annie Spratt on Unsplash
“曾经沧海难为水,除却巫山不是云。 ——(唐)元稹《离思五首·其四》 ”
xarray 中的DataArray 和 Dataset 对象除了上节介绍过的直接手动创建之外,更多的情况下却是通过其他数据储存结构转换和存储在硬盘中的数据存储文件读取而来。
例如转换 pandas[1] 类型数据为 xarray 类型或者读取一些数据文件,如NetCDF[2]文件或zarr[3]文件。
pandas
若要由pandas对象转换为 xarray 对象或者由 xarray 转为pandas对象,可以对pandas[4] 对象使用to_xarray[5]方法或者对 xarray 对象使用to_pandas[6]方法进行转换。
import pandas as pd
import numpy as np
import xarray as xr
series = pd.Series(np.ones((10,)), index=list("abcdefghij"))
series

运行结果
我们先导入 pandas 包和 numpy 包,为方便后续的代码书写,as关键词对 pandas、numpy 定义了 pd、np 两个别名。
pandas(pd)包中的 Series 函数能够创建一维数组,np.ones((10,))创建了一个一维的 10 个全为 1 的数列,其结果如下所示

np.ones((10,))创建结果
在 python 中 List 函数能够将元组转为列表。对于字符串而言,可以将字符串中的各个字符提取出来,其结果如下所示

list("abcdefghij")运行结果
上述的 list 函数创建了一个列表。这个列表赋予了 index 值。index 是相应数据的索引。

索引和数据
综上,对于 pd.Series 函数的理解可如下进行理解

pd.Series函数
若要将变量 series(pandas 类型)转为 xarray 类型只需在变量后加上.to_xarray()方法即可。
arr = series.to_xarray()
arr

运行结果
由于只有一个变量,所以转换的结果是 xarray 中的DataArray类型。
若要将 xarray 转为 pandas 类型,类似的在变量后加上.to_pandas()
arr.to_pandas()

运行结果
对于 xarray 的多变量Dataset对象同理可用类似对pandas对象的转换方法,只需要在对象后添加to_series /to_dataframe即可:
先创建一个Dataset对象ds
ds = xr.Dataset(
data_vars={"a": ("x", np.arange(5)), "b": (("x", "y"), np.ones((5, 4)))}
)
ds

对象ds
to_series:将多变量数据DataSet使用多重索引,将相应的DataArray对象转换为pandas列表对象。
将 ds(Dataset)中的变量a转换为 pandas 类型
ds.a.to_series()

ds.a.to_series()
如何理解这一句代码呢?ds.a获得了ds这个 DataSet 中的变量a的 DataArray

ds.a
接着我们把这个 DataArray 利用.to_series()转换为 pandas 中的 Series(列表)类型。由于没有指定 index,则在默认情况下,index 默认为数字且从 0 开始,步长为 1.
如果要指定 index,则需在转换为 pandas 类型后,对 index 进行指定,比如
myseries = ds.a.to_series()
myseries.index=list("sylsy")
myseries
myseries = ds.a.to_series()获得了 pandas 类型的 myseries 列表。对这个列表通过.index指定其索引。最终获得具有新索引的列表 myseries。

经过index替换的列表
“目前不能在
.to_series()中直接指定 index。 ”
同理也可将 ds(Dataset)中的变量b转换为 pandas 类型
ds.b.to_series()

ds.b.to_series()
可以发现 pandas 列表类型不能离散存储数据,在这种情况下数据发生了广播(broadcast)

离散数据存储

广播数据对其连续化
这样的情况下就保证了每一个 a 都对应了 b 中的一行数据。
to_dataframe:将DataArray或Dataset对象转换为pandas.dataframe(数据框)。注意到DataArray对象名称与转换为数据框的名称一样都为a。
ds.a.to_dataframe()

ds.a.to_dataframe()
类似于转换为列表,为保证数据的连续性,对于转换为DataFrame数组也会发生广播。
ds.to_dataframe()

ds.to_dataframe()
Xarray 最广泛使用的特性之一是它读写各种数据格式的能力。例如,Xarray 可以读取以下格式:
open_dataset / open_mfdataset, to_netcdf / save_mfdataset)open_zarr, to_zarr)open_rasterio)
存储 Xarray 数据结构的推荐方法是 NetCDF(Network Common Data Form),这是一种二进制文件格式,用于起源于地球科学的自描述数据集。文件的后缀为.nc。Xarray 基于 netCDF 数据模型,因此磁盘上的 netCDF 文件直接对应于数据集对象。
Xarray 采用open_dataset / open_dataarray 函数读取NetCDF 文件,采用to_netcdf方法将数据写入文件。
接下来首先创建一些数据集,并使用to_netcdf将数据写入硬盘
ds1 = xr.Dataset(
data_vars={
"a": (("x", "y"), np.random.randn(4, 2)),
"b": (("z", "x"), np.random.randn(6, 4)),
},
coords={
"x": np.arange(4),
"y": np.arange(-2, 0),
"z": np.arange(-3, 3),
},
)
ds2 = xr.Dataset(
data_vars={
"a": (("x", "y"), np.random.randn(7, 3)),
"b": (("z", "x"), np.random.randn(2, 7)),
},
coords={
"x": np.arange(6, 13),
"y": np.arange(3),
"z": np.arange(3, 5),
},
)
将 DataSets 和 DataArray 写入 nc 文件中
# DataSets写入文件
ds1.to_netcdf("ds1.nc")
ds2.to_netcdf("ds2.nc")
# DataArray写入文件
ds1.a.to_netcdf("da1.nc")

路径下的生成的nc文件
通过Panoply[11]软件可以很容易浏览刚才成功生成的三个文件

Panoply浏览nc文件
读取这些文件也很简单:
ds1 = xr.open_dataset("ds1.nc")
ds1

xr.open_dataset("ds1.nc")
ds1 = xr.open_dataarray("ds1.nc")
ds1

xr.open_dataarray("da1.nc")

Zarr包
Zarr[12]是一个 Python 包和数据格式,实现了分块、压缩、n 维数组的储存。这种数据格式对于并行计算是非常友好的。
Zarr 能够以多种方式存储阵列,包括内存、文件和基于云的对象存储,如 Amazon S3 和谷歌云存储。Xarray 的 Zarr 后端允许 Xarray 利用这些功能。
若没有安装过 Zarr 包,可以通过pip 安装
pip install zarr

或者通过conda进行安装
conda install -c conda-forge zarr
如果要确认是否安装成功,可以通过运行测试套件得以确认(可以不用运行)。
pip install pytest
python -m pytest -v --pyargs zarr
大致会得到以下结果


以及对应路径下(此处以 D 盘的根目录为例)的临时文件(运行完毕可以删除)。

xarray 对象可以能用to_zarr[13]方式以 Zarr 文件的形式写入到硬盘。
import zarr
ds1.to_zarr("ds1.zarr", mode="w")

此时可以获得一个文件夹ds1.zarr。

文件夹ds1.zarr
“
mode参数:w表示创建(如果存在,则覆盖);w-表示创建(如果存在则失败);a表示覆盖现有变量(如果不存在则创建)。 ”
读取 zarr 文件
xr.open_zarr("ds1.zarr", chunks=None)
将 chunks(分块)参数设置为 None 可以避免 dask 数组(在后面的章节中会详细介绍)。
[1]
pandas: https://pandas.pydata.org/
[2]
NetCDF: https://www.unidata.ucar.edu/software/netcdf/
[3]
zarr: https://zarr.readthedocs.io/en/stable/
[4]
pandas: https://zarr.readthedocs.io/en/stable/
[5]
to_xarray: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_xarray.html
[6]
to_pandas: http://xarray.pydata.org/en/stable/generated/xarray.DataArray.to_pandas.html
[7]
NetCDF: https://www.unidata.ucar.edu/software/netcdf/
[8]
Zarr: https://zarr.readthedocs.io/en/stable/
[9]
GeoTIFF: https://gdal.org/drivers/raster/gtiff.html
[10]
GDAL rasters: https://svn.osgeo.org/gdal/tags/gdal_1_2_5/frmts/formats_list.html
[11]
Panoply: https://www.giss.nasa.gov/tools/panoply/
[12]
Zarr: https://zarr.readthedocs.io/en/stable/
[13]
to_zarr: http://xarray.pydata.org/en/stable/generated/xarray.Dataset.to_zarr.html