xarray概述
- 创建DataArray
- 索引(Indexing)
- 属性(Attributes)
- 计算(Computation)
- GroupBy
- 绘图(Plotting)
- pandas
- Datasets
- 读写netCDF文件
以下是可以使用对象的事例。更多详细信息可以参阅剩余其他文档。
首先,导入 numpy, pandas 和 xarray,并使用他们的缩写:
In [1]: import numpy as np
In [2]: import pandas as pd
In [3]: import xarray as xr
创建DataArray
我们可以通过以 numpy 数组或列表的形式提供数据,和可选的参数 dimensions
和 coordinates
,来从头开始创建DataArray:
In [4]: data = xr.DataArray(np.random.randn(2, 3),
...: dims=('x', 'y'),
...: coords={'x': [10, 20]})
...:
In [5]: data
Out[5]:
<xarray.DataArray (x: 2, y: 3)>
array([[ 0.276, -1.087, -0.674],
[ 0.114, -1.478, 0.525]])
Coordinates:
* x (x) int64 10 20
Dimensions without coordinates: y
在此例中,我们创建了一个二维array
,将dimensions
分别命名为 x
,y
,并赋予 x
维度 10
、20
两个坐标标签。如果提供的是一个pandas的Series
或DataFrame
,元数据将会被直接拷贝:
In [6]: xr.DataArray(pd.Series(range(3), index=list('abc'), name='foo'))
Out[6]:
<xarray.DataArray 'foo' (dim_0: 3)>
array([0, 1, 2])
Coordinates:
* dim_0 (dim_0) object 'a' 'b' 'c'
以下是DataArray
的一些关键属性:
# 与 pandas 一样, values 是一个可以就地修改的 numpy array
In [7]: data.values
Out[7]:
array([[ 0.276, -1.087, -0.674],
[ 0.114, -1.478, 0.525]])
In [8]: data.dims
Out[8]: ('x', 'y')
In [9]: data.coords
Out[9]:
Coordinates:
* x (x) int64 10 20
# 可以使用此字典存储任意元数据
In [10]: data.attrs
Out[10]: {}
更多 DataArray
内容,请参阅:xarray数据结构之DataArray
索引(Indexing)
xarray 支持4种索引方式。因为已经给 x
维度赋予了坐标标签,我们可以像 pandas 一样沿着该维度使用基于标签的方式索引。
# 通过整数标签定位的位置索引, 类似 numpy
In [11]: data[0, :]
Out[11]:
<xarray.DataArray (y: 3)>
array([ 0.276, -1.087, -0.674])
Coordinates:
x int64 10
Dimensions without coordinates: y
# loc 或 "location": 通过坐标标签定位的位置索引, 类似 pandas
In [12]: data.loc[10]
Out[12]:
<xarray.DataArray (y: 3)>
array([ 0.276, -1.087, -0.674])
Coordinates:
x int64 10
Dimensions without coordinates: y
# isel 或 "integer select": 通过维度名称和整数标签
In [13]: data.isel(x=0)
Out[13]:
<xarray.DataArray (y: 3)>
array([ 0.276, -1.087, -0.674])
Coordinates:
x int64 10
Dimensions without coordinates: y
# sel 或 "select": 通过维度名称和坐标标签
In [14]: data.sel(x=10)
Out[14]:
<xarray.DataArray (y: 3)>
array([ 0.276, -1.087, -0.674])
Coordinates:
x int64 10
Dimensions without coordinates: y
与位置索引不同的是,基于标签的索引方式可以使我们不知道 array 的组织结构的条件下进行索引。我们只需知道维度的名称和我们想要索引的标签。例如:(x=10)
可以进行索引,不需要知道 x 是数组的第一维还是第二维,也不需要知道 10 是 x 的第一个元素还是第二个元素。我们已经在创建数据时告诉xarray,x是第一个维度:xarray会跟踪该数据,而我们不必进行此操作。有关更多内容,请参阅: Indexing and selecting data 。
属性(Attributes)
当设置DataArray
时,通常会去设置元数据属性。一个有用选择是去设置 ['long_name']
和 ['units']
,因为 xarray 在绘图时会自动使用他们来进行标记(如果有的话)。我们选择的这些特殊名称遵循 NetCDF Climate and Forecast (CF) Metadata Conventions 。attrs
仅仅是一个Python字典,所以你可以赋予任何你希望的内容。
In [15]: data.attrs['long_name'] = 'random velocity'
In [16]: data.attrs['units'] = 'metres/sec'
In [17]: data.attrs['description'] = 'A random variable created as an example.'
In [18]: data.attrs['random_attribute'] = 123
In [19]: data.attrs
Out[19]:
{'long_name': 'random velocity',
'units': 'metres/sec',
'description': 'A random variable created as an example.',
'random_attribute': 123}
# 你也可以给坐标轴添加元数据
In [20]: data.x.attrs['units'] = 'x units'
计算(Computation)
Data arrays
的计算方式与 numpy ndarrays
非常相似:
In [21]: data + 10
Out[21]:
<xarray.DataArray (x: 2, y: 3)>
array([[10.276, 8.913, 9.326],
[10.114, 8.522, 10.525]])
Coordinates:
* x (x) int64 10 20
Dimensions without coordinates: y
In [22]: np.sin(data)
Out[22]:
<xarray.DataArray (x: 2, y: 3)>
array([[ 0.273, -0.885, -0.624],
[ 0.113, -0.996, 0.501]])
Coordinates:
* x (x) int64 10 20
Dimensions without coordinates: y
# 转置(transpose)
In [23]: data.T
Out[23]:
<xarray.DataArray (y: 3, x: 2)>
array([[ 0.276, 0.114],
[-1.087, -1.478],
[-0.674, 0.525]])
Coordinates:
* x (x) int64 10 20
Dimensions without coordinates: y
Attributes:
long_name: random velocity
units: metres/sec
description: A random variable created as an example.
random_attribute: 123
In [24]: data.sum()
Out[24]:
<xarray.DataArray ()>
array(-2.325)
但是,聚合操作可以使用维度名称代替轴号:
In [25]: data.mean(dim='x')
Out[25]:
<xarray.DataArray (y: 3)>
array([ 0.195, -1.283, -0.074])
Dimensions without coordinates: y
算数运算根据维名称进行广播。 这意味着无需插入虚拟维度即可对齐:
In [26]: a = xr.DataArray(np.random.randn(3), [data.coords['y']])
In [27]: b = xr.DataArray(np.random.randn(4), dims='z')
In [28]: a
Out[28]:
<xarray.DataArray (y: 3)>
array([ 0.405, 0.577, -1.715])
Coordinates:
* y (y) int64 0 1 2
In [29]: b
Out[29]:
<xarray.DataArray (z: 4)>
array([-1.039, -0.371, -1.158, -1.344])
Dimensions without coordinates: z
In [30]: a + b
Out[30]:
<xarray.DataArray (y: 3, z: 4)>
array([[-0.635, 0.034, -0.753, -0.94 ],
[-0.462, 0.206, -0.581, -0.767],
[-2.754, -2.086, -2.873, -3.059]])
Coordinates:
* y (y) int64 0 1 2
Dimensions without coordinates: z
这也意味着在大多数情况下,您无需担心维度顺序:
In [31]: data - data.T
Out[31]:
<xarray.DataArray (x: 2, y: 3)>
array([[0., 0., 0.],
[0., 0., 0.]])
Coordinates:
* x (x) int64 10 20
Dimensions without coordinates: y
运算也根据索引标签对齐:
In [32]: data[:-1] - data[:1]
Out[32]:
<xarray.DataArray (x: 1, y: 3)>
array([[0., 0., 0.]])
Coordinates:
* x (x) int64 10
Dimensions without coordinates: y
更多内容,请参阅:Computation 。
GroupBy
xarray 使用与 pandas 非常相似的 API ,进行分组操作(参阅: xarray教程之GroupBy: split-apply-combine)。
In [33]: labels = xr.DataArray(['E', 'F', 'E'], [data.coords['y']], name='labels')
In [34]: labels
Out[34]:
<xarray.DataArray 'labels' (y: 3)>
array(['E', 'F', 'E'], dtype='<U1')
Coordinates:
* y (y) int64 0 1 2
In [35]: data.groupby(labels).mean('y')
Out[35]:
<xarray.DataArray (x: 2, labels: 2)>
array([[-0.199, -1.087],
[ 0.319, -1.478]])
Coordinates:
* x (x) int64 10 20
* labels (labels) object 'E' 'F'
In [36]: data.groupby(labels).map(lambda x: x - x.min())
Out[36]:
<xarray.DataArray (x: 2, y: 3)>
array([[0.95 , 0.391, 0. ],
[0.787, 0. , 1.199]])
Coordinates:
* x (x) int64 10 20
* y (y) int64 0 1 2
labels (y) <U1 'E' 'F' 'E'
绘图(Plotting)
可视化数据集是非常快速便捷的:
In [37]: data.plot()
Out[37]: <matplotlib.collections.QuadMesh at 0x7fc2c3a15d50>
注意自动产生的标签带有名称和单位。我们在添加元数据属性方面的努力取得了回报!这些图的许多方面都是可以自定义的:参阅 Plotting 。
pandas
Xarray对象可以通过使用 to_series()
, to_dataframe()
和 to_xarray()
方法,轻松地与pandas对象之间进行转换:
In [38]: series = data.to_series()
In [39]: series
Out[39]:
x y
10 0 0.276232
1 -1.087401
2 -0.673690
20 0 0.113648
1 -1.478427
2 0.524988
dtype: float64
# convert back
In [40]: series.to_xarray()
Out[40]:
<xarray.DataArray (x: 2, y: 3)>
array([[ 0.276, -1.087, -0.674],
[ 0.114, -1.478, 0.525]])
Coordinates:
* x (x) int64 10 20
* y (y) int64 0 1 2
Datasets
是一个被赋予
DataArray
的类似字典(dict) 的容器。你可以认为它是一个具有多维结构的 :
In [41]: ds = xr.Dataset({'foo': data, 'bar': ('x', [1, 2]), 'baz': np.pi})
In [42]: ds
Out[42]:
<xarray.Dataset>
Dimensions: (x: 2, y: 3)
Coordinates:
* x (x) int64 10 20
Dimensions without coordinates: y
Data variables:
foo (x, y) float64 0.2762 -1.087 -0.6737 0.1136 -1.478 0.525
bar (x) int64 1 2
baz float64 3.142
上面的操作将创建一个数据集,包含三个分别名为 foo
,bar
和 baz
的DataArray
实例。 使用字典或点索引(相当于使用属性)将Dataset
变量提取为DataArray
对象,但请注意,赋值操作仅适用于字典索引:
In [43]: ds['foo']
Out[43]:
<xarray.DataArray 'foo' (x: 2, y: 3)>
array([[ 0.276, -1.087, -0.674],
[ 0.114, -1.478, 0.525]])
Coordinates:
* x (x) int64 10 20
Dimensions without coordinates: y
Attributes:
long_name: random velocity
units: metres/sec
description: A random variable created as an example.
random_attribute: 123
In [44]: ds.foo
Out[44]:
<xarray.DataArray 'foo' (x: 2, y: 3)>
array([[ 0.276, -1.087, -0.674],
[ 0.114, -1.478, 0.525]])
Coordinates:
* x (x) int64 10 20
Dimensions without coordinates: y
Attributes:
long_name: random velocity
units: metres/sec
description: A random variable created as an example.
random_attribute: 123
在创建 ds
时,我们指定 foo
与之前创建的data
相同,bar
具有一个维度 x
及关联值“ 1”和“ 2”,而baz
是不与 ds
中任何维度关联的标量。 数据集中的变量可以具有不同的 dtype
甚至不同的维度,但是所有维度涉及的点都在相同共享的坐标系统内。即,如果两个变量的维度均为x
,则该维度在两个变量中必须一致。
例如,在创建 ds
xarray 时,它会自动将bar
与DataArray
foo
对齐,即它们共享相同的坐标系,从而['x'] == ['x'] == ds['x']
。 因此,以下操作在创建 ds['bar']
时无需显式指定坐标 x :
In [45]: ds.bar.sel(x=10)
Out[45]:
<xarray.DataArray 'bar' ()>
array(1)
Coordinates:
x int64 10
如果希望一次使用多个变量,则几乎可以将DataArray
对象与Dataset
对象(包括索引和算术)一起做。
更多 Dataset
内容,请参阅:xarray数据结构之Dataset
读写netCDF文件
NetCDF是xarray对象的推荐文件格式。地球科学的用户会发现,Dataset
数据模型看起来与netCDF文件非常相似(实际上是它的灵感来源)。
你可以通过使用 to_netcdf()
, open_dataset()
与 open_dataarray()
直接将 xarray 对象读写到磁盘:
In [46]: ds.to_netcdf('')
In [47]: xr.open_dataset('')
Out[47]:
<xarray.Dataset>
Dimensions: (x: 2, y: 3)
Coordinates:
* x (x) int64 10 20
Dimensions without coordinates: y
Data variables:
foo (x, y) float64 ...
bar (x) int64 ...
baz float64 ...
数据集通常分布在多个文件中(通常一个时间对应一个文件)。 xarray通过提供 open_mfdataset()
和 save_mfdataset()
方法来支持此用例。更多有关内容,请参阅:Reading and writing files