在xarray中原地更新属性

7

我对使用xarrays还比较新,我想原地修改NetCDF文件的属性。但是内置函数只提供了另一个新数据集。

ds = xr.open_dataset(file_)
# ds has "time" as one of the coordinates whose attributes I want to modify
#here is ds for more clarity
ds
>><xarray.Dataset>
Dimensions:  (lat: 361, lev: 1, lon: 720, time: 1)
Coordinates:
* lon      (lon) float32 0.0 0.5 1.0 1.5 2.0 ... 357.5 358.0 358.5 359.0 359.5
* lat      (lat) float32 -90.0 -89.5 -89.0 -88.5 -88.0 ... 88.5 89.0 89.5 90.0
* lev      (lev) float32 1.0
* time     (time) timedelta64[ns] 00:00:00
Data variables:
V        (time, lev, lat, lon) float32 ...
Attributes:
Conventions:          CF
constants_file_name:  P20000101_12
institution:          IACETH
lonmin:               0.0
lonmax:               359.5
latmin:               -90.0
latmax:               90.0
levmin:               250.0
levmax:               250.0

我尝试分配新属性,但它给了一个新的数据数组。

newtimeattr = "some time" 
ds.time.assign_attrs(units=newtimeattr)

另外,如果我将这个属性分配给数据集变量 "V",它会添加另一个变量到数据集

ds['V '] = ds.V.assign_attrs(units='m/s')
## here it added another variable V .So, ds has 2 variables with same name as V
ds #trimmed output
>>Data variables:
V        (time, lev, lat, lon) float32 ...
V        (time, lev, lat, lon) float32 ...
2个回答

8

从xarray文档中,xarray.DataArray.assign_attrs

返回一个等效于self.attrs.update(*args, **kwargs)的新对象。

这意味着该方法返回一个具有更新attrs的新DataArray(或坐标),您必须将其分配给数据集以使其更新:

ds.coords["time"] = ds.time.assign_attrs(
    units=newtimeattr
)

就像你指出的一样,可以通过使用关键字语法访问属性来在原地完成此操作:

ds.time.attrs['units'] = newtimeattr

需要澄清的一点是:您最后一个语句添加新变量的原因是,您将ds.V更新的属性赋给了变量ds['V '] 有一个空格。由于在Python中,'V ' != 'V',因此这创建了一个新变量,并将其赋值为原始ds.V的值,在更新属性后。否则,您的方法将正常工作:

ds['V'] = ds.V.assign_attrs(units='m/s')

没错,感谢您的敏锐观察并指出错误。 - Light_B

7
ds.V.attrs['units'] = 'm/s'

对我很有用。同样对于“时间”,它是一个维度。
ds.time.attrs['units'] = newtimeattr

嗯,我在想,为什么这个语法是标准的: ds.time.attrs['units'] = newtimeattr。人们很容易将“time”与Python方法或Python变量混淆。我更喜欢像 ds['time'].attrs['units'] = newtimeattr 这样的语法,因为这里的 time 明显声明为NC变量。幸运的是它也能正常工作。 - jurajb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接