向 xarray 数据集添加 'constant' 维度
Add 'constant' dimension to xarray Dataset
我有一系列 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)
但是当我尝试添加另一个维度来传达有关时间的信息时(所有数据都来自同一个 year/month),事情开始变糟。
我试过两种破解方法:
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'],然后回到 xr.Dataset.from_dataframe()
的数据集。我已经试过了——但是在我终止进程之前需要 20 多分钟。
有谁知道如何获得每月 'time' 维度的数据集?
你的第一个例子非常接近:
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')
您会注意到我的版本有一些变化:
- 我将第一个传递给 'time' 坐标而不是标量。您需要传入一个列表或一维数组来获取一维坐标变量,如果您还使用 'time' 作为维度,这就是您所需要的。这就是错误
ValueError: Coordinate objects must be 1-dimensional
试图告诉您的内容(顺便说一句——如果您有关于如何使该错误消息更有用的想法,我洗耳恭听!)。
- 我正在为 DataArray 构造函数提供一个
dims
参数。传入(无序)字典有点危险,因为无法保证迭代顺序。
- 我也切换到
datetime.datetime
而不是 pd.datetime
。后者只是前者的别名
另一种明智的方法是在添加 'time' 作为标量坐标后,将 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')
此版本很好地概括了将几天的数据连接在一起的情况——您只需将 DataArray 列表加长即可。根据我的经验,大多数时候你首先想要额外维度的原因是能够沿着它连接。否则长度 1 尺寸不是很有用。
您可以使用.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]))
我有一系列 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)
但是当我尝试添加另一个维度来传达有关时间的信息时(所有数据都来自同一个 year/month),事情开始变糟。
我试过两种破解方法:
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'],然后回到 xr.Dataset.from_dataframe()
的数据集。我已经试过了——但是在我终止进程之前需要 20 多分钟。
有谁知道如何获得每月 'time' 维度的数据集?
你的第一个例子非常接近:
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')
您会注意到我的版本有一些变化:
- 我将第一个传递给 'time' 坐标而不是标量。您需要传入一个列表或一维数组来获取一维坐标变量,如果您还使用 'time' 作为维度,这就是您所需要的。这就是错误
ValueError: Coordinate objects must be 1-dimensional
试图告诉您的内容(顺便说一句——如果您有关于如何使该错误消息更有用的想法,我洗耳恭听!)。 - 我正在为 DataArray 构造函数提供一个
dims
参数。传入(无序)字典有点危险,因为无法保证迭代顺序。 - 我也切换到
datetime.datetime
而不是pd.datetime
。后者只是前者的别名
另一种明智的方法是在添加 'time' 作为标量坐标后,将 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')
此版本很好地概括了将几天的数据连接在一起的情况——您只需将 DataArray 列表加长即可。根据我的经验,大多数时候你首先想要额外维度的原因是能够沿着它连接。否则长度 1 尺寸不是很有用。
您可以使用.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]))