xarray指南:合并数据 - 连接
目录
本文翻译自 xarray 官方文档 Combining data 的部分内容。
本文介绍如何使用 xarray 实现沿单个纬度合并 DataArray
或 Dataset
。
简介
- 有关沿单个维度组合数据集或数据数组的信息,请参阅 concatenate。
- 有关合并具有不同变量的数据集,请参见 merge。
- 有关合并具有不同索引或缺失值的数据集或数据数组的信息,请参见 combine。
- 有关沿多个维度组合数据集或数据数组的信息,请参见 combining.multi。
准备
加载需要使用到的库。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import xarray as xr
xr.set_options(display_style="text")
Concatenate
想要沿着已经存在或新的维度将数组合并为一个更大的数组,可以使用 concat()
。
concat
接收一个可迭代的 DataArray
或 Dataset
对象,以及一个维度名称,沿着该维度进行连接。
arr = xr.DataArray(
np.random.randn(2, 3),
[
('x', ['a', 'b']),
('y', [10, 20, 30])
]
)
arr[:, :1]
<xarray.DataArray (x: 2, y: 1)>
array([[0.89269944],
[0.05413846]])
Coordinates:
* x (x) <U1 'a' 'b'
* y (y) int64 10
类似于使用 np.concatenate
的方式
xr.concat([arr[:, :1], arr[:, 1:]], dim='y')
<xarray.DataArray (x: 2, y: 3)>
array([[ 0.89269944, 0.73344603, -0.96442539],
[ 0.05413846, -2.15066399, -1.54335184]])
Coordinates:
* x (x) <U1 'a' 'b'
* y (y) int64 10 20 30
除了沿现有维度合并外,concat
可以通过将较低维度的数组堆叠在一起来创建新维度。
arr[0]
<xarray.DataArray (y: 3)>
array([ 0.89269944, 0.73344603, -0.96442539])
Coordinates:
x <U1 'a'
* y (y) int64 10 20 30
想要将一维数组合并为二维数组,可以用 np.array
xr.concat([arr[0], arr[1]], "x")
<xarray.DataArray (x: 2, y: 3)>
array([[ 0.89269944, 0.73344603, -0.96442539],
[ 0.05413846, -2.15066399, -1.54335184]])
Coordinates:
* y (y) int64 10 20 30
* x (x) object 'a' 'b'
如果 concat
的第二个参数是一个新的维度名称,数据将会沿着该维度连接,该维度将成为第一个维度。
xr.concat([arr[0], arr[1]], 'new_dim')
<xarray.DataArray (new_dim: 2, y: 3)>
array([[ 0.89269944, 0.73344603, -0.96442539],
[ 0.05413846, -2.15066399, -1.54335184]])
Coordinates:
* y (y) int64 10 20 30
x (new_dim) <U1 'a' 'b'
Dimensions without coordinates: new_dim
concat
第二个参数也可以是 Index
或 DataArray
对象,或者字符串,这种情况下,将用于标记新维度。
xr.concat([arr[0], arr[1]], pd.Index([-90, -100], name='new_dim'))
<xarray.DataArray (new_dim: 2, y: 3)>
array([[ 0.89269944, 0.73344603, -0.96442539],
[ 0.05413846, -2.15066399, -1.54335184]])
Coordinates:
* y (y) int64 10 20 30
x (new_dim) <U1 'a' 'b'
* new_dim (new_dim) int64 -90 -100
当然,concat
也可以用在 Dataset
对象中。
ds = arr.to_dataset(name='foo')
xr.concat([ds.sel(x='a'), ds.sel(x='b')], 'x')
<xarray.Dataset>
Dimensions: (x: 2, y: 3)
Coordinates:
* y (y) int64 10 20 30
* x (x) object 'a' 'b'
Data variables:
foo (x, y) float64 0.8927 0.7334 -0.9644 0.05414 -2.151 -1.543
concat
有一些参数,可以更深入地控制变量如何连接以及如何处理数据集之间的变量冲突。
使用默认参数时,xarray 将在内存中加载部分坐标变量,用于不同数据集间的比较。
如果通过使用 Dask 并行计算来延迟操纵数据集,这可能会导致过高的代价。
实战
使用 nwpc-oper/nwpc-data 封装的 cfgrib 接口加载数据,使用该项目封装的数据查找接口在 CMA-PI 上查找业务系统生成的数据文件。
from nwpc_data.grib.cfgrib import load_field_from_file
from nwpc_data.data_finder import find_local_file
从 000 时效文件中加载 4 个层次的温度场。
temp_vars = []
for level in [500, 700, 850, 900]:
t = load_field_from_file(
file_path=find_local_file(
"grapes_gfs_gmf/grib2/orig",
start_time="2020031800",
forecast_time="0h"
),
parameter="t",
level_type="isobaricInhPa",
level=level,
)
temp_vars.append(t)
沿层次坐标 isobaricInhPa
连接
xr.concat(temp_vars, dim="isobaricInhPa")
<xarray.DataArray 't' (isobaricInhPa: 4, latitude: 720, longitude: 1440)>
array([[[232.26372, 232.00372, 232.04172, ..., 232.08672, 232.11572,
231.90472],
...skip...
[238.72554, 238.78555, 238.74554, ..., 238.51555, 238.93555,
238.80554]]], dtype=float32)
Coordinates:
time datetime64[ns] 2020-03-18
step timedelta64[ns] 00:00:00
valid_time datetime64[ns] 2020-03-18
* latitude (latitude) float64 89.88 89.62 89.38 ... -89.38 -89.62 -89.88
* longitude (longitude) float64 0.0 0.25 0.5 0.75 ... 359.2 359.5 359.8
* isobaricInhPa (isobaricInhPa) int64 500 700 850 900
Attributes:
GRIB_paramId: 130
...skip...
standard_name: air_temperature
使用一个新的维度 level
连接
xr.concat(temp_vars, dim="level")
<xarray.DataArray 't' (level: 4, latitude: 720, longitude: 1440)>
array([[[232.26372, 232.00372, 232.04172, ..., 232.08672, 232.11572,
231.90472],
...skip...
[238.72554, 238.78555, 238.74554, ..., 238.51555, 238.93555,
238.80554]]], dtype=float32)
Coordinates:
time datetime64[ns] 2020-03-18
step timedelta64[ns] 00:00:00
valid_time datetime64[ns] 2020-03-18
* latitude (latitude) float64 89.88 89.62 89.38 ... -89.38 -89.62 -89.88
* longitude (longitude) float64 0.0 0.25 0.5 0.75 ... 359.2 359.5 359.8
isobaricInhPa (level) int64 500 700 850 900
Dimensions without coordinates: level
Attributes:
GRIB_paramId: 130
...skip...
standard_name: air_temperature
使用 pandas.Index
作为参数
xr.concat(
temp_vars,
pd.Index(["500hPa", "700hPa", "850hPa", "900hPa"], name="level"),
)
<xarray.DataArray 't' (level: 4, latitude: 720, longitude: 1440)>
array([[[232.26372, 232.00372, 232.04172, ..., 232.08672, 232.11572,
231.90472],
...skip...
[238.72554, 238.78555, 238.74554, ..., 238.51555, 238.93555,
238.80554]]], dtype=float32)
Coordinates:
time datetime64[ns] 2020-03-18
step timedelta64[ns] 00:00:00
valid_time datetime64[ns] 2020-03-18
* latitude (latitude) float64 89.88 89.62 89.38 ... -89.38 -89.62 -89.88
* longitude (longitude) float64 0.0 0.25 0.5 0.75 ... 359.2 359.5 359.8
isobaricInhPa (level) int64 500 700 850 900
* level (level) object '500hPa' '700hPa' '850hPa' '900hPa'
Attributes:
GRIB_paramId: 130
...skip...
standard_name: air_temperature