为xarray数据集添加“常量”维度

时间:2016-05-11 21:27:56

标签: python python-xarray

我有一系列CSV格式的月度网格化数据集。我想阅读它们,添加几个维度,然后写入netcdf。我以前在使用xarray(xray)方面有很棒的经验,所以我想在这个任务中使用它。

我可以轻松地将它们变成2D DataArray,例如:

data = np.ones((360,720))
lats = np.arange(-89.75, 90, 0.5) * -1
lngs = np.arange(-179.75, 180, 0.5)
coords =  {'lat': lats, 'lng':lngs}
da = xr.DataArray(data, coords=coords)

但是,当我尝试添加另一个维度时,它将传达有关时间的信息(所有数据来自同一年/月),事情开始变得糟糕。

我尝试过两种破解方法:

1)将输入数据扩展为m x n x 1,类似于:

data = np.ones((360,720))
lats = np.arange(-89.75, 90, 0.5) * -1
lngs = np.arange(-179.75, 180, 0.5)
coords =  {'lat': lats, 'lng':lngs}
data = data[:,:,np.newaxis]

然后我按照上面的步骤进行操作,更新了coords以包含第三维。

lats = np.arange(-89.75, 90, 0.5) * -1
lngs = np.arange(-179.75, 180, 0.5)
coords =  {'lat': lats, 'lng':lngs}
coords['time'] = pd.datetime(year, month, day))
da = xr.DataArray(data, coords=coords)
da.to_dataset(name='variable_name')

这对于创建DataArray很好 - 但是当我尝试转换为数据集时(因此我可以写入netCDF),我得到一个关于'ValueError:Coordinate objects必须是1维'的错误

2)我尝试的第二种方法是将数据阵列投射到数据帧,将索引设置为['lat','lng','time'],然后返回到{{{ 1}}。我试过这个 - 但是在我杀死这个过程之前需要20多分钟。

有谁知道如何获得每月“时间”维度的数据集?

2 个答案:

答案 0 :(得分:10)

你的第一个例子非常接近:

lats = np.arange(-89.75, 90, 0.5) * -1
lngs = np.arange(-179.75, 180, 0.5)
coords =  {'lat': lats, 'lng': lngs}
coords['time'] = [datetime.datetime(year, month, day)]
da = xr.DataArray(data, coords=coords, dims=['lat', 'lng', 'time'])
da.to_dataset(name='variable_name')

您的版本会发现一些变化:

  1. 我在第一时间过了一段时间'坐标而不是标量。您需要传入一个列表或1d数组来获取一维坐标变量,如果您还使用了' time'作为一个维度。这就是错误ValueError: Coordinate objects must be 1-dimensional试图告诉您的内容(顺便说一下 - 如果您有关于如何使该错误消息更有帮助的想法,我全心全意!)。
  2. 我向DataArray构造函数提供了dims参数。传入(非有序)字典有点危险,因为迭代顺序无法保证。
  3. 我也改为datetime.datetime而不是pd.datetime。后者只是前者的别名。
  4. 另一种明智的做法是,一旦您添加了“时间”,就会将concat与一个项目列表结合使用。作为标量坐标,例如,

    lats = np.arange(-89.75, 90, 0.5) * -1
    lngs = np.arange(-179.75, 180, 0.5)
    coords =  {'lat': lats, 'lng': lngs, 'time': datetime.datetime(year, month, day)}
    da = xr.DataArray(data, coords=coords, dims=['lat', 'lng'])
    expanded_da = xr.concat([da], 'time')
    

    这个版本很好地概括了很多时候将数据连接在一起 - 你只需要更长时间地列出DataArrays。根据我的经验,大多数时候,你首先想要额外维度的原因是能够沿着它连接。长度1尺寸不是很有用。

答案 1 :(得分:2)

您可以使用.expand_dims()添加新尺寸,并使用.assign_coords()添加相应尺寸的坐标值。下面的代码将new_dim维添加到ds数据集中,并使用您提供的list_of_values设置相应的cordcornate。

expanded_ds = ds.expand_dims("new_dim").assign_coords(new_dim=("new_dim", [list_of_values]))