Xarray在Python中如何将独立的日期和小时维度合并为一个时间维度?

3

我有一个xarray数据集:

Jupyter cell output of xarray

如您所见,这些维度是(纬度,经度,时间步长(小时),时间(天))。我想将小时和天合并为一个,以便维度变为(纬度,经度,时间步长)。我该如何做?

如果您能提供一些代码来生成一个与实际数据具有相同坐标和维度的小示例数据集,而不仅仅是屏幕截图,那将非常有帮助。 - astoeriko
1个回答

3

创建一维时间维度和坐标

您可以使用 stack 方法创建时间和步骤维度的多级索引。由于您的 valid_time 坐标已经具有正确的 datetime 维度,因此您还可以删除多级索引坐标,仅保留带有实际日期时间的 valid_time 坐标。

import numpy as np
import xarray as xr
import pandas as pd

# Create a dummy representation of your data
ds = xr.Dataset(
    data_vars={"a": (("x", "y", "time", "step"), np.random.rand(5, 5, 3, 24))},
    coords={
        "time": pd.date_range(start="1999-12-31", periods=3, freq="d"),
        "step": pd.timedelta_range(start="1h", freq="h", periods=24),
    },
)
ds = ds.assign_coords(valid_time=ds.time + ds.step)

# Stack the time and step dims
stacked_ds = ds.stack(datetime=("time", "step"))

# Drop the multiindex if you want to keep only the valid_time coord which
# contains the combined date and time information.
# Rename vars and dims to your liking.
stacked_ds = (
    stacked_ds.drop_vars("datetime")
    .rename_dims({"datetime": "time"})
    .rename_vars({"valid_time": "time"})
)
print(stacked_ds)

<xarray.Dataset>
Dimensions:  (time: 72, x: 5, y: 5)
Coordinates:
  * time     (time) datetime64[ns] 1999-12-31T01:00:00 ... 2000-01-03
Dimensions without coordinates: x, y
Data variables:
    a        (x, y, time) float64 0.1961 0.3733 0.2227 ... 0.4929 0.7459 0.4106

将时间坐标变为索引

这样我们就创建了一个具有连续日期时间序列作为坐标的单个时间维度。然而,它不是一个索引。对于一些方法,比如resample,时间需要成为索引。 我们可以通过显式地将其设置为索引来解决这个问题:

stacked_ds.set_index(time="time")

然而,这将使“时间”成为一个变量而不是坐标。要再次将其变为坐标,我们可以使用:
stacked_ds.set_index(time="time").set_coords("time")

使用DataArrays处理数据

您也可以在DataArrays上堆叠维度。但是,它们没有rename_dimsrename_vars方法。相反,您可以使用swap_dimsrename

(
    ds.a.stack(datetime=("time", "step"))
    .drop_vars("datetime")
    .swap_dims({"datetime": "time"})
    .rename({"valid_time": "time"})
).set_index(time="time")

谢谢!这似乎有效 - 但是为了让它工作,我不得不将我的xr数据数组转换为xr数据集!我只是不确定它是否做到了我想要的。当我尝试将此输出重采样为每月时,会出现KeyError:'time'。尝试使用stacked_ds.resample(time ="1M").mean() - HM14
1
有趣。据我所知,问题是time需要成为索引,但目前不是。我们可以通过使用stacked_ds.set_index(time="time")显式地将其设置为索引来解决这个问题。然后重新采样应该就能起作用了。将time设置为索引,出于某种原因会使它成为变量而不是coord,但我们可以通过使用set_coords("time")来修复它。 - astoeriko

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接