将“时间”维度添加到二维 (x, y) NetCDF 文件中的有效方法,该文件具有在不同时间重复同一变量的变量

Effective way to add "time" dimension to two dimensional (x, y) NetCDF file, which has variables reprecenting same variable at different times

提问人:Jugilismaani 提问时间:8/2/2023 更新时间:8/2/2023 访问量:52

问:

我有带有 x 和 y 坐标的 CSV 文件,以及三个不同时间步长的变量值,如下所示:

x, y, var_t1, var_t2, var_t3,
1, 1, 8,      8,      6
1, 2, 6,      1,      2
2, 1, 5,      3,      7
2, 2, 7,      2,      6

我学会了使用以下方法创建 NetCDF 文件:

import xarray as xr
xr.Dataset.from_dataframe(df.set_index(['x', 'y'])).to_netcdf('filename.nc')

这导致了一个以 x 和 y 为维度的 NetCDF,我得到了 3 个不同的变量。

我的目标是创建一个 NetCDF,其中 x、y 和 t 作为维度,使用单个变量。

我设法做到了这一点,但我觉得我以一种非常复杂的方式做到了。

我的解决方案是使用 CSV 文件并使其长 3 倍,同时添加一个“t”列来表示时间步长:

x, y, t, var_t1, var_t2, var_t3,
1, 1, 0, 8,      0,      0
1, 2, 0, 6,      0,      0
2, 1, 0, 5,      0,      0
2, 2, 0, 7,      0,      0
1, 1, 1, 0,      8,      0
1, 2, 1, 0,      1,      0
2, 1, 1, 0,      3,      0
2, 2, 1, 0,      2,      0
1, 1, 2, 0,      0,      6
1, 2, 2, 0,      0,      2
2, 1, 2, 0,      0,      7
2, 2, 2, 0,      0,      6

现在当我申请时

import xarray as xr
xr.Dataset.from_dataframe(df.set_index(['x', 'y', 't'])).to_netcdf('filename.nc')

我得到一个具有 x、y、t 维度的 NetCDF,并且每个不同时间(即当 t = 1 时,只有 var_t2 != 0)的单个变量。

有没有办法以更简单的方式实现这一点,以防将来遇到类似的问题?这很容易用 3 个时间步长来完成,但我会遇到几十或几千个时间步长的麻烦。

谢谢!

python csv netcdf python-xarray 维度

评论


答:

2赞 jspaeth 8/2/2023 #1

假设你有数据帧:df

>> df
x  y  var_t1  var_t2  var_t3
0  1  1       8       8       6
1  1  2       6       1       2
2  2  1       5       3       7
3  2  2       7       2       6

您可以将 x,y 设置为索引,将其转换为 xarray,合并变量var_t1...设置为新维度,并设置为时间维度的坐标:new_times

>> ds = df.set_index(["x", "y"]).to_xarray()
>> ds
<xarray.Dataset>
Dimensions:  (x: 2, y: 2)
Coordinates:
  * x        (x) int64 1 2
  * y        (y) int64 1 2
Data variables:
    var_t1   (x, y) int64 8 6 5 7
    var_t2   (x, y) int64 8 1 3 2
    var_t3   (x, y) int64 6 2 7 6


>> new_times = range(3)
>> ds_result = ds.to_array(dim="time").assign_coords(time=new_times)
>> ds_result
<xarray.DataArray (time: 3, x: 2, y: 2)>
array([[[8, 6],
        [5, 7]],

       [[8, 1],
        [3, 2]],

       [[6, 2],
        [7, 6]]])
Coordinates:
  * x        (x) int64 1 2
  * y        (y) int64 1 2
  * time     (time) int64 0 1 2