坐标
坐标是存储在 DataArray 和 Dataset 的 coords 属性中的辅助变量。
>> ds.coords
Coordinates:
lat (x, y) float64 42.25 42.21 42.63 42.59
lon (x, y) float64 -99.83 -99.32 -99.79 -99.23
* time (time) datetime64[ns] 2014-09-06 2014-09-07 2014-09-08
reference_time datetime64[ns] 2014-09-05
day (time) int32 6 7 8
和属性不同的是,xarray 会在转换对象时对坐标进行解释并维持坐标变量。xarray中的坐标有两种类型:
注:
xarray 中的术语和 CF 中的术语不同。CF中的维度坐标称作坐标变量,而非维度坐标称作辅助坐标变量 [注1]。CF是指 Climate and Forecast [注2]。
更改坐标
如果要完整的添加或移除坐标数组,你可以使用类字典语法(如上所示)。
如果要在数据和坐标之间反复转换,可以使用 set_coords 和 reset_coords 方法(均直接返回新对象)。
转换非维度坐标变量为数据变量:
>> ds.reset_coords()
<xarray.Dataset>
Dimensions: (time: 3, x: 2, y: 2)
Coordinates:
* time (time) datetime64[ns] 2014-09-06 2014-09-07 2014-09-08
Dimensions without coordinates: x, y
Data variables:
temperature (x, y, time) float64 24.24 12.34 8.215 26.03 25.4 21.89 ...
precipitation (x, y, time) float64 9.558 4.379 0.302 9.394 4.124 1.06 ...
lat (x, y) float64 42.25 42.21 42.63 42.59
lon (x, y) float64 -99.83 -99.32 -99.79 -99.23
reference_time datetime64[ns] 2014-09-05
day (time) int32 6 7 8
注意:除了维度坐标变量之外,其余的非维度坐标变量均转换为坐标变量。
转换数据变量为坐标变量:
>> ds.set_coords(['temperature', 'precipitation'])
<xarray.Dataset>
Dimensions: (time: 3, x: 2, y: 2)
Coordinates:
temperature (x, y, time) float64 24.24 12.34 8.215 26.03 25.4 21.89 ...
precipitation (x, y, time) float64 9.558 4.379 0.302 9.394 4.124 1.06 ...
lat (x, y) float64 42.25 42.21 42.63 42.59
lon (x, y) float64 -99.83 -99.32 -99.79 -99.23
* time (time) datetime64[ns] 2014-09-06 2014-09-07 2014-09-08
reference_time datetime64[ns] 2014-09-05
day (time) int32 6 7 8
Dimensions without coordinates: x, y
Data variables:
*empty*
转换后并删除其余变量,返回的新对象仅包含了 temperature 变量和 time 坐标变量:
>> ds['temperature'].reset_coords(drop=True)
<xarray.DataArray 'temperature' (x: 2, y: 2, time: 3)>
array([[[ 24.243747, 12.342479, 8.214643],
[ 26.02749 , 25.404077, 21.892622]],
[[ 5.357696, 8.754152, 5.254765],
[ 8.359619, 17.393205, 32.886064]]])
Coordinates:
* time (time) datetime64[ns] 2014-09-06 2014-09-07 2014-09-08
Dimensions without coordinates: x, y
坐标方法
坐标(Coordinates
)对象也有一些非常有用的方法,比如将其转换为 Dataset:
>> ds.coords.to_dataset()
<xarray.Dataset>
Dimensions: (time: 3, x: 2, y: 2)
Coordinates:
* time (time) datetime64[ns] 2014-09-06 2014-09-07 2014-09-08
lon (x, y) float64 -99.83 -99.32 -99.79 -99.23
reference_time datetime64[ns] 2014-09-05
day (time) int32 6 7 8
lat (x, y) float64 42.25 42.21 42.63 42.59
Dimensions without coordinates: x, y
Data variables:
*empty*
merge 方法也非常有趣,因为它使用了和算数操作中合并坐标的相同逻辑。
>> alt = xr.Dataset(coords={'z': [10], 'lat': 0, 'lon': 0})
>> alt
<xarray.Dataset>
Dimensions: (z: 1)
Coordinates:
* z (z) int32 10
lon int32 0
lat int32 0
Data variables:
*empty*
>> ds.coords.merge(alt.coords)
<xarray.Dataset>
Dimensions: (time: 3, z: 1)
Coordinates:
* time (time) datetime64[ns] 2014-09-06 2014-09-07 2014-09-08
reference_time datetime64[ns] 2014-09-05
day (time) int32 6 7 8
* z (z) int32 10
Data variables:
*empty*
注意:合并之后就有了两个维度坐标变量。
如果你想对 xarray 对象进行二元操作时, coords.merge 方法就显得非常有用了。
索引
使用 .to_index 方法可以将坐标转换为 pandas.Index:
>> ds['time'].to_index()
DatetimeIndex(['2014-09-06', '2014-09-07', '2014-09-08'], dtype='datetime64[ns]', name='time', freq='D')
懒人用法(Dataset 和 DataArray 均可):
>> ds.indexes
time: DatetimeIndex(['2014-09-06', '2014-09-07', '2014-09-08'], dtype='datetime64[ns]', name='time', freq='D')
注意: index 的对象只能是1D变量。当对 lon 或 lat 进行 index 操作时会报错。
MultiIndex 坐标
xarray 支持使用 pandas.MultiIndex 标记坐标值:
>> midx = pd.MultiIndex.from_arrays([['R', 'R', 'V', 'V'], [.1, .2, .7, .9]], names=('band', 'wn'))
>> midx
MultiIndex(levels=[['R', 'V'], [0.1, 0.2, 0.7, 0.9]],
labels=[[0, 0, 1, 1], [0, 1, 2, 3]],
names=['band', 'wn'])
>> mda = xr.DataArray(np.random.rand(4), coords={'spec': midx}, dims='spec')
>> mda
<xarray.DataArray (spec: 4)>
array([ 0.323193, 0.545577, 0.005243, 0.641758])
Coordinates:
* spec (spec) MultiIndex
- band (spec) object 'R' 'R' 'V' 'V'
- wn (spec) float64 0.1 0.2 0.7 0.9
为了方便多索引层直接通过 'virtual' 或 'derived' 坐标获取(打印 Dataset 或 DataArray 时用 - 标记):
说人话:即都可以通过类字典方法或属性的方式获取数据。
>> mda['band']
<xarray.DataArray 'band' (spec: 4)>
array(['R', 'R', 'V', 'V'], dtype=object)
Coordinates:
* spec (spec) MultiIndex
- band (spec) object 'R' 'R' 'V' 'V'
- wn (spec) float64 0.1 0.2 0.7 0.9
>> mda.wn
<xarray.DataArray 'wn' (spec: 4)>
array([ 0.1, 0.2, 0.7, 0.9])
Coordinates:
* spec (spec) MultiIndex
- band (spec) object 'R' 'R' 'V' 'V'
- wn (spec) float64 0.1 0.2 0.7 0.9
有时也可以使用 sel 方法代替使用多索引层索引时 (见 Multi-level indexing [注3]):
和其它坐标不同的是,'virtual' 层坐标是不会存储在 DataArray 和 Dataset 对象的 coords 属性中的,尽管打印时会显示出来。 因此,大部分坐标方法都不能对它应用。也不能用于替换特定层。
因为在 Dataset 和 DataArray 对象中每个多索引层都可以通过 ‘virtual’ 坐标获取,它的名称不能与相同对象的其它层,坐标和数据变量的名称冲突。尽管 xarray 会提供默认值,但是还是推荐明确指定名称。
注1:https://github.com/pydata/xarray/issues/1295
注2:http://cfconventions.org/cf-conventions/v1.6.0/cf-conventions.html#terminology
注3:https://xray.readthedocs.io/en/stable/indexing.html#multi-level-indexing