前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >xarry | 快速入门

xarry | 快速入门

作者头像
bugsuse
发布2020-04-21 17:22:27
2.1K0
发布2020-04-21 17:22:27
举报
文章被收录于专栏:气象杂货铺气象杂货铺

xarray (之前的 xray) 是一个开源的python库。通过提供 pandas 的核心数据结构N维变形功能,从而将 pandas 的标签数据功能应用到物理科学领域。主要是想提供一个类似pandas并且能与pandas兼容的工具包来进行多维数组(而不是pandas 所擅长的表格数据)分析。采用的是地球科学领域广泛使用的自描述数据通用数据模型实现上述功能。

下面通过一些示例快速入门:

代码语言:javascript
复制
In [1]: import numpy as np

In [2]: import pandas as pd

In [3]: import xarray as xr

创建 DataArray

利用 numpy 数组或列表可以创建 DataArray ( coords 和 dims 为可选参数)

代码语言:javascript
复制
In [4]: xr.DataArray(np.random.randn(2, 3))
Out[4]: 
<xarray.DataArray (dim_0: 2, dim_1: 3)>
array([[ 1.643563, -1.469388,  0.357021],
       [-0.6746  , -1.776904, -0.968914]])
Dimensions without coordinates: dim_0, dim_1

In [5]: data = xr.DataArray(np.random.randn(2, 3), coords={'x': ['a', 'b']}, dims=('x', 'y'))

In [6]: data
Out[6]: 
<xarray.DataArray (x: 2, y: 3)>
array([[-1.294524,  0.413738,  0.276662],
       [-0.472035, -0.01396 , -0.362543]])
Coordinates:
  * x        (x) <U1 'a' 'b'
Dimensions without coordinates: y

如果使用 Series 或 DataFrame 创建 DataArray,创建时将直接复制元数据信息:

代码语言:javascript
复制
In [7]: xr.DataArray(pd.Series(range(3), index=list('abc'), name='foo'))
Out[7]: 
<xarray.DataArray 'foo' (dim_0: 3)>
array([0, 1, 2])
Coordinates:
  * dim_0    (dim_0) object 'a' 'b' 'c'

下面是 DataArray 的一些属性:

代码语言:javascript
复制
# 类似 pandas 操作,可以直接赋值改变值 
In [8]: data.values
Out[8]: 
array([[-1.295,  0.414,  0.277],
       [-0.472, -0.014, -0.363]])

In [9]: data.dims
Out[9]: ('x', 'y')

In [10]: data.coords
Out[10]: 
Coordinates:
  * x        (x) <U1 'a' 'b'

# 可以使用字典存储元数据
In [11]: data.attrs
Out[11]: OrderedDict()

索引

xarray 借鉴了 pandas 的索引机制,因此在索引时非常快。xarray提供了四种索引方式:

代码语言:javascript
复制
# 通过整数进行索引
In [12]: data[[0, 1]]
Out[12]: 
<xarray.DataArray (x: 2, y: 3)>
array([[-1.294524,  0.413738,  0.276662],
       [-0.472035, -0.01396 , -0.362543]])
Coordinates:
  * x        (x) <U1 'a' 'b'
Dimensions without coordinates: y

# 通过坐标标签索引
In [13]: data.loc['a':'b']
Out[13]: 
<xarray.DataArray (x: 2, y: 3)>
array([[-1.294524,  0.413738,  0.276662],
       [-0.472035, -0.01396 , -0.362543]])
Coordinates:
  * x        (x) <U1 'a' 'b'
Dimensions without coordinates: y

# 通过维度名和整数标签索引
In [14]: data.isel(x=slice(2))
Out[14]: 
<xarray.DataArray (x: 2, y: 3)>
array([[-1.294524,  0.413738,  0.276662],
       [-0.472035, -0.01396 , -0.362543]])
Coordinates:
  * x        (x) <U1 'a' 'b'
Dimensions without coordinates: y

# 利用维度名和坐标标签
In [15]: data.sel(x=['a', 'b'])
Out[15]: 
<xarray.DataArray (x: 2, y: 3)>
array([[-1.294524,  0.413738,  0.276662],
       [-0.472035, -0.01396 , -0.362543]])
Coordinates:
  * x        (x) <U1 'a' 'b'
Dimensions without coordinates: y

计算

数组计算方式类似 numpy.ndarray

代码语言:javascript
复制
In [16]: data + 10
Out[16]: 
<xarray.DataArray (x: 2, y: 3)>
array([[  8.705476,  10.413738,  10.276662],
       [  9.527965,   9.98604 ,   9.637457]])
Coordinates:
  * x        (x) <U1 'a' 'b'
Dimensions without coordinates: y

In [17]: np.sin(data)
Out[17]: 
<xarray.DataArray (x: 2, y: 3)>
array([[-0.962079,  0.402035,  0.273146],
       [-0.454699, -0.013959, -0.354653]])
Coordinates:
  * x        (x) <U1 'a' 'b'
Dimensions without coordinates: y

In [18]: data.T
Out[18]: 
<xarray.DataArray (y: 3, x: 2)>
array([[-1.294524, -0.472035],
       [ 0.413738, -0.01396 ],
       [ 0.276662, -0.362543]])
Coordinates:
  * x        (x) <U1 'a' 'b'
Dimensions without coordinates: y

In [19]: data.sum()
Out[19]: 
<xarray.DataArray ()>
array(-1.4526610277231344)

但在集合操作时使用维度名代替轴:

代码语言:javascript
复制
In [20]: data.mean(dim='x')
Out[20]: 
<xarray.DataArray (y: 3)>
array([-0.883279,  0.199889, -0.042941])
Dimensions without coordinates: y

利用基于维度名的方式进行广播计算操作。这意味着不需要关心对齐操作:

代码语言:javascript
复制
In [21]: a = xr.DataArray(np.random.randn(3), [data.coords['y']])

In [22]: b = xr.DataArray(np.random.randn(4), dims='z')

In [23]: a
Out[23]: 
<xarray.DataArray (y: 3)>
array([-0.006154, -0.923061,  0.895717])
Coordinates:
  * y        (y) int64 0 1 2

In [24]: b
Out[24]: 
<xarray.DataArray (z: 4)>
array([ 0.805244, -1.206412,  2.565646,  1.431256])
Dimensions without coordinates: z

In [25]: a + b
Out[25]: 
<xarray.DataArray (y: 3, z: 4)>
array([[ 0.79909 , -1.212565,  2.559492,  1.425102],
       [-0.117817, -2.129472,  1.642585,  0.508195],
       [ 1.700961, -0.310694,  3.461363,  2.326973]])
Coordinates:
  * y        (y) int64 0 1 2
Dimensions without coordinates: z

而且大多数情况下你都不要关心维度的顺序:

代码语言:javascript
复制
In [26]: data - data.T
Out[26]: 
<xarray.DataArray (x: 2, y: 3)>
array([[ 0.,  0.,  0.],
       [ 0.,  0.,  0.]])
Coordinates:
  * x        (x) <U1 'a' 'b'
Dimensions without coordinates: y

以及基于索引标签的对齐操作:

代码语言:javascript
复制
In [27]: data[:-1] - data[:1]
Out[27]: 
<xarray.DataArray (x: 1, y: 3)>
array([[ 0.,  0.,  0.]])
Coordinates:
  * x        (x) <U1 'a'
Dimensions without coordinates: y

GroupBy

使用类似 pandas 的 API 支持组操作

代码语言:javascript
复制
In [28]: labels = xr.DataArray(['E', 'F', 'E'], [data.coords['y']], name='labels')

In [29]: labels
Out[29]: 
<xarray.DataArray 'labels' (y: 3)>
array(['E', 'F', 'E'], 
      dtype='<U1')
Coordinates:
  * y        (y) int64 0 1 2

In [30]: data.groupby(labels).mean('y')
Out[30]: 
<xarray.DataArray (x: 2, labels: 2)>
array([[-0.508931,  0.413738],
       [-0.417289, -0.01396 ]])
Coordinates:
  * x        (x) <U1 'a' 'b'
  * labels   (labels) object 'E' 'F'

In [31]: data.groupby(labels).apply(lambda x: x - x.min())
Out[31]: 
<xarray.DataArray (x: 2, y: 3)>
array([[ 0.      ,  0.427698,  1.571185],
       [ 0.822489,  0.      ,  0.931981]])
Coordinates:
  * x        (x) <U1 'a' 'b'
  * y        (y) int64 0 1 2
    labels   (y) <U1 'E' 'F' 'E'

pandas

xarray 对象 和 pandas 对象 可以非常方便的互相转换

代码语言:javascript
复制
In [32]: series = data.to_series()

In [33]: series
Out[33]: 
x  y
a  0   -1.294524
   1    0.413738
   2    0.276662
b  0   -0.472035
   1   -0.013960
   2   -0.362543
dtype: float64

# 反转换操作
In [34]: series.to_xarray()
Out[34]: 
<xarray.DataArray (x: 2, y: 3)>
array([[-1.294524,  0.413738,  0.276662],
       [-0.472035, -0.01396 , -0.362543]])
Coordinates:
  * x        (x) object 'a' 'b'
  * y        (y) int64 0 1 2

Dataset

xarray.Dataset 是 xarray.DataArray 对象的类字典容器,也可以认为这是一个多维的 DataFrame。

代码语言:javascript
复制
In [35]: ds = xr.Dataset({'foo': data, 'bar': ('x', [1, 2]), 'baz': np.pi})

In [36]: ds
Out[36]: 
<xarray.Dataset>
Dimensions:  (x: 2, y: 3)
Coordinates:
  * x        (x) <U1 'a' 'b'
Dimensions without coordinates: y
Data variables:
    baz      float64 3.142
    foo      (x, y) float64 -1.295 0.4137 0.2767 -0.472 -0.01396 -0.3625
    bar      (x) int64 1 2

使用字典方法提取 DataSet 变量为 DataArray 对象:

代码语言:javascript
复制
In [37]: ds['foo']
Out[37]: 
<xarray.DataArray 'foo' (x: 2, y: 3)>
array([[-1.294524,  0.413738,  0.276662],
       [-0.472035, -0.01396 , -0.362543]])
Coordinates:
  * x        (x) <U1 'a' 'b'
Dimensions without coordinates: y

数据集中的变量可以有不同的类型甚至不同的维度。

Dataset 所使用的操作几乎全部适用于 DataArray 对象。

NetCDF

使用 to_netcdf,open_dataset 和 open_dataarray 方法可以直接读取及写 xarray 对象。

代码语言:javascript
复制
In [38]: ds.to_netcdf('example.nc')

In [39]: xr.open_dataset('example.nc')
Out[39]: 
<xarray.Dataset>
Dimensions:  (x: 2, y: 3)
Coordinates:
  * x        (x) object 'a' 'b'
Dimensions without coordinates: y
Data variables:
    baz      float64 3.142
    foo      (x, y) float64 -1.295 0.4137 0.2767 -0.472 -0.01396 -0.3625
    bar      (x) int64 1 2

后面会介绍一些更详细的内容。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-08-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 气象杂货铺 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • GroupBy
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档