【问题标题】:Add 'constant' dimension to xarray Dataset将“常量”维度添加到 xarray 数据集
【发布时间】:2016-09-07 12:01:06
【问题描述】:

我有一系列 CSV 格式的每月网格数据集。我想阅读它们,添加一些维度,然后写入 netcdf。我过去在使用 xarray (xray) 方面拥有丰富的经验,所以我想我会使用 if 来完成这项任务。

我可以通过以下方式轻松地将它们放入 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]

然后我按照与上述相同的步骤,更新坐标以包含第三个维度。

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 must be 1-dimensional”的错误

2) 我尝试的第二种方法是使用我的数据数组,将其转换为数据帧,将索引设置为 ['lat','lng', 'time'] 然后返回到带有 @987654324 的数据集@。我已经尝试过了——但在我终止进程之前需要 20 多分钟。

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

【问题讨论】:

  • 感谢您的提问。如果您可以发布完全可重复的示例,使其更容易参与。不管怎样,我稍后会看看
  • @Maximilian 进行了一些编辑以支持复制/粘贴——我不经常在这里提问,所以如果您认为任何进一步的编辑/样式更改可能会有所帮助,我将不胜感激。
  • 斯蒂芬给出了理想的答案,所以我不会试图击败它。感谢您的编辑,好多了...如果您真的想要将来再改进,您的代码行可以是块(请注意 Stephan 在下面是如何做的)

标签: python python-xarray


【解决方案1】:

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

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. 我将传入第一个“时间”坐标而不是标量。您需要传入一个列表或一维数组来获取一维坐标变量,如果您还使用“时间”作为维度,这就是您所需要的。这就是错误 ValueError: Coordinate objects must be 1-dimensional 试图告诉您的内容(顺便说一下,如果您有关于如何使该错误消息更有帮助的想法,我会全力以赴!)。
  2. 我正在为 DataArray 构造函数提供一个dims 参数。传入(无序)字典有点危险,因为不能保证迭代顺序。
  3. 我也切换到datetime.datetime,而不是pd.datetime。后者只是前者的别名。

另一种明智的方法是在将“时间”添加为标量坐标后,将 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 维度不是很有用。

【讨论】:

  • 我最终选择了第二种方法——这让我可以灵活地将我的 lat/lng 数据保留为 360x720 数组,并减少我在原始文件中为自己做的一些额外步骤问题的表述。
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 2016-12-14
    • 1970-01-01
    • 2020-11-01
    • 2017-01-30
    • 1970-01-01
    • 2023-01-07
    • 2017-10-01
    • 2020-06-15
    • 1970-01-01
    相关资源
    最近更新 更多