从多个numpy数组创建xarray - 时间序列

1 人关注

我想用一系列的numpy数组创建一个Xarray DataArray,其坐标如下:年度时间序列数据(比方说在一个均匀的1500X1500矩阵上的温度)。

('时间', '长度', '纬度')

  • time (time) datetime64[ns] 2000-12-31 2001-12-31 ... 2020-12-31
  • lon (lon) float64 -19.98 -19.93 -19.88 -19.82 ... 54.88 54.93 54.98
  • lat (lat) float64 39.97 39.92 39.87 39.82 ... -34.88 -34.93 -34.98
  • 我使用的原始('原始')时间序列数据被存储为单独的文件,文件名表示时间序列中的每一年(也就是说,数据文件本身没有提供时间信息,只是在名称中,temp2000.xxx,temp2001.xxx,等等)。我将这些单独的数据文件导入单独的numpy数组中,这些数组有一个空间维度(对应上面的纬度/纬度),但除了我指定的变量名称外没有时间维度。

    我想知道如何将所有这些numpy数组合并成一个多维xarray DataArray,其中包括numpy数组的lat/lon和由时间变量(取自文件名)定义的时间。

    这可能是很直接的,但我想不明白。

    temp2000 = np.random.rand(1500, 1500)
    xll = -20.0
    xur = 55.0
    yll = -35.0
    yur = 40.0
    cellsize = 0.1
    lon_tup = np.arange(xll, xur, cellsize) + (cellsize / 2)
    lat_tup = np.arange(yll, yur, cellsize)
    lat_tup = lat_tup[::-1] + (cellsize / 2)
    time2 = pd.date_range("2000-01-01", freq="Y", periods=21)
    ds = xr.DataArray(
                coords=[time2, lat_tup, lon_tup], dims=["time", "lat", "lon"])
    ds["Temperature_2000"] = (["time", "lat", "lon"], temp2000)
    

    DataArray创建得很好,但显然numpy数组不能被添加,因为它缺乏 "时间 "维度。我可以通过一个单独的步骤强制添加时间维度吗?例子只是一个时间步骤(2000年),为了说明问题,用假的数据。

    python
    arrays
    numpy
    python-xarray
    Pamela G
    Pamela G
    发布于 2021-11-16
    2 个回答
    Michael Delgado
    Michael Delgado
    发布于 2021-11-22
    已采纳
    0 人赞同

    你只能用反映数据实际形状的维数来初始化DataArray。因此,你可以重塑你的numpy数组,使其包含一个额外的维度(例如,用 reshape or np.expand_dims ),或者将DataArray创建为 (lat, lon) ,然后再添加额外的维度(例如用 da.expand_dims ),如本例中。

    da = xr.DataArray(
        temp2000,
        coords=[lon_tup, lat_tup],
        dims=["lon", "lat"],
    # expand the array to include a length-1 time dimension
    # corresponding to the file's time indicator
    da = da.expand_dims(time=pd.Index([2000], name="time"))
    

    另外,你也可以在准备串联数据之前排除时间上的模糊。

    arrays = []
    time = pd.date_range("2000-01-01", freq="Y", periods=21)
    years = time.year
    for y in years:
        # read in your data as (lat, lon)
        arrays.append(da)
    # concat using a full TimeIndex to give the values of time as well as the name
    result = xr.concat(arrays, dim=time)
    

    还要注意xarray Datasets(通常缩写为ds)和DataArrays(通常缩写为da)之间的区别,前者基本上是DataArrays的字典,后者是xarray的基本数组单元。数据集对于与存储的交互和组织你的工作流程是很有用的,对于在多个数组上应用相同的操作也是很有帮助的,但是在大多数情况下,当你做数学运算时,你想用数组来工作。请看xarray的文档数据结构 for more info.

    谢谢你,Michael。我最终将各个numpy数组重塑为[1, 1500, 1500],然后将它们串联成一个维度为[21, 1500, 1500]的大数组。然后我可以使用da = xr.DataArray(data=largearray, coords=[years, lat_tup, lon_tup], dims=["year", "lat", "lon"]),它可以完美地工作。
    Pamela G
    Pamela G
    发布于 2021-11-22
    0 人赞同

    感谢Michael Delgado的指导。以下是我的解决方案。

    xll = -20.0
    xur = 55.0
    yll = -35.0
    yur = 40.0
    cellsize = 0.1
    lon_tup = np.arange(xll, xur, cellsize) + (cellsize / 2)
    lat_tup = np.arange(yll, yur, cellsize)
    lat_tup = lat_tup[::-1] + (cellsize / 2)
    StartYear = 2000
    EndYear = 2020
    for x in range(StartYear, EndYear):
        # filein would be the data read in from the external file
        filein = np.random.rand(1500, 1500)
        temp = np.resize(filein, (1,1500,1500))
        temp[:, 0, 0] = x
        if x == StartYear:
            array_wbm = temp
        else:
            array_wbm = np.concatenate(([array_wbm, temp]), axis=0)
    time = pd.date_range("2000-01-01", freq="Y", periods=21)
    years = time.year