Python 如何更正Xarray数据集中的时间日历等元数据属性?

Python 如何更正Xarray数据集中的时间日历等元数据属性?,python,python-xarray,Python,Python Xarray,不幸的是,我正在读取到xarray中的NetCDF文件在时间坐标上具有calendar属性,指定为gregorian\u proleptic,而不是CF标准proleptic\u gregorian 我怎样才能解决这个问题 我试图更改属性,但xarray必须已经将该元数据存储在我需要修改的其他地方,因为当我尝试使用解码\u cf时,它仍然认为日历是格里高利的。以下是我尝试过的: import xarray as xr import fsspec url='s3://noaa-ofs-pds/d

不幸的是,我正在读取到xarray中的NetCDF文件在时间坐标上具有calendar属性,指定为
gregorian\u proleptic
,而不是CF标准
proleptic\u gregorian

我怎样才能解决这个问题

我试图更改属性,但xarray必须已经将该元数据存储在我需要修改的其他地方,因为当我尝试使用
解码\u cf
时,它仍然认为日历是
格里高利的。以下是我尝试过的:

import xarray as xr
import fsspec

url='s3://noaa-ofs-pds/dbofs.20200826/nos.dbofs.fields.f044.20200826.t06z.nc'
ncfile = fsspec.open(url)
ds = xr.open_dataset(ncfile.open(), decode_times=False)

ds.ocean_time.attrs['calendar']='proleptic_gregorian'

xr.decode_cf(ds, decode_times=True)
产生:

---------------------------------------------------------------------------
OutOfBoundsDatetime                       Traceback (most recent call last)
/srv/conda/envs/notebook/lib/python3.7/site-packages/xarray/coding/times.py in decode_cf_datetime(num_dates, units, calendar, use_cftime)
    157         try:
--> 158             dates = _decode_datetime_with_pandas(flat_num_dates, units, calendar)
    159         except (KeyError, OutOfBoundsDatetime, OverflowError):

/srv/conda/envs/notebook/lib/python3.7/site-packages/xarray/coding/times.py in _decode_datetime_with_pandas(flat_num_dates, units, calendar)
    105             "Cannot decode times from a non-standard calendar, {!r}, using "
--> 106             "pandas.".format(calendar)
    107         )

OutOfBoundsDatetime: Cannot decode times from a non-standard calendar, 'gregorian_proleptic', using pandas.

During handling of the above exception, another exception occurred:

KeyError                                  Traceback (most recent call last)
/srv/conda/envs/notebook/lib/python3.7/site-packages/xarray/coding/times.py in _decode_cf_datetime_dtype(data, units, calendar, use_cftime)
     76     try:
---> 77         result = decode_cf_datetime(example_value, units, calendar, use_cftime)
     78     except Exception:

/srv/conda/envs/notebook/lib/python3.7/site-packages/xarray/coding/times.py in decode_cf_datetime(num_dates, units, calendar, use_cftime)
    160             dates = _decode_datetime_with_cftime(
--> 161                 flat_num_dates.astype(float), units, calendar
    162             )

/srv/conda/envs/notebook/lib/python3.7/site-packages/xarray/coding/times.py in _decode_datetime_with_cftime(num_dates, units, calendar)
     97     return np.asarray(
---> 98         cftime.num2date(num_dates, units, calendar, only_use_cftime_datetimes=True)
     99     )

cftime/_cftime.pyx in cftime._cftime.num2date()

cftime/_cftime.pyx in cftime._cftime.to_calendar_specific_datetime()

KeyError: 'gregorian_proleptic'

During handling of the above exception, another exception occurred:

ValueError                                Traceback (most recent call last)
<ipython-input-41-174237fc09de> in <module>
----> 1 xr.decode_cf(ds, decode_times=True)

/srv/conda/envs/notebook/lib/python3.7/site-packages/xarray/conventions.py in decode_cf(obj, concat_characters, mask_and_scale, decode_times, decode_coords, drop_variables, use_cftime, decode_timedelta)
    594         drop_variables=drop_variables,
    595         use_cftime=use_cftime,
--> 596         decode_timedelta=decode_timedelta,
    597     )
    598     ds = Dataset(vars, attrs=attrs)

/srv/conda/envs/notebook/lib/python3.7/site-packages/xarray/conventions.py in decode_cf_variables(variables, attributes, concat_characters, mask_and_scale, decode_times, decode_coords, drop_variables, use_cftime, decode_timedelta)
    496             stack_char_dim=stack_char_dim,
    497             use_cftime=use_cftime,
--> 498             decode_timedelta=decode_timedelta,
    499         )
    500         if decode_coords:

/srv/conda/envs/notebook/lib/python3.7/site-packages/xarray/conventions.py in decode_cf_variable(name, var, concat_characters, mask_and_scale, decode_times, decode_endianness, stack_char_dim, use_cftime, decode_timedelta)
    336         var = times.CFTimedeltaCoder().decode(var, name=name)
    337     if decode_times:
--> 338         var = times.CFDatetimeCoder(use_cftime=use_cftime).decode(var, name=name)
    339 
    340     dimensions, data, attributes, encoding = variables.unpack_for_decoding(var)

/srv/conda/envs/notebook/lib/python3.7/site-packages/xarray/coding/times.py in decode(self, variable, name)
    425             units = pop_to(attrs, encoding, "units")
    426             calendar = pop_to(attrs, encoding, "calendar")
--> 427             dtype = _decode_cf_datetime_dtype(data, units, calendar, self.use_cftime)
    428             transform = partial(
    429                 decode_cf_datetime,

/srv/conda/envs/notebook/lib/python3.7/site-packages/xarray/coding/times.py in _decode_cf_datetime_dtype(data, units, calendar, use_cftime)
     85             "if it is not installed."
     86         )
---> 87         raise ValueError(msg)
     88     else:
     89         dtype = getattr(result, "dtype", np.dtype("object"))

ValueError: unable to decode time units 'days since 2016-01-01 00:00:00' with "calendar 'gregorian_proleptic'". Try opening your dataset with decode_times=False or installing cftime if it is not installed.
---------------------------------------------------------------------------
边界外数据回溯(最近一次呼叫最后一次)
/解码中的srv/conda/envs/notebook/lib/python3.7/site-packages/xarray/coding/times.py
157尝试:
-->158个日期=\u解码\u日期时间\u与\u熊猫(平面\u数字\u日期、单位、日历)
159除外(键错误、超出边界时间、溢出错误):
/srv/conda/envs/notebook/lib/python3.7/site-packages/xarray/coding/times.py in_decode_datetime_与_pandas(平面数字日期、单位、日历)
105“无法使用从非标准日历{!r}解码时间”
-->106“熊猫”。格式(日历)
107         )
OutOfBoundsDatetime:无法使用熊猫从非标准日历“gregorian_proleptic”中解码时间。
在处理上述异常期间,发生了另一个异常:
KeyError回溯(最近一次呼叫最后一次)
/srv/conda/envs/notebook/lib/python3.7/site-packages/xarray/coding/times.py in_decode_cf_datetime_dtype(数据、单位、日历、使用时间)
76尝试:
--->77结果=解码日期时间(例如值、单位、日历、使用时间)
78例外情况除外:
/解码中的srv/conda/envs/notebook/lib/python3.7/site-packages/xarray/coding/times.py
160日期=\u解码\u日期时间\u与\u cftime(
-->161个日期。类型(浮动),单位,日历
162             )
/srv/conda/envs/notebook/lib/python3.7/site-packages/xarray/coding/times.py in_decode_datetime_with_cftime(num_日期、单位、日历)
97返回np.asarray(
--->98 cftime.num2date(num_日期、单位、日历,仅限使用日期时间=True)
99     )
cftime/\u cftime.pyx,单位为cftime.\u cftime.num2date()
cftime/\u cftime.pyx,单位为cftime.\u cftime.to\u calendar\u specific\u datetime()
关键错误:“gregorian_proleptic”
在处理上述异常期间,发生了另一个异常:
ValueError回溯(最近一次调用上次)
在里面
---->1 xr.decode\u cf(ds,decode\u times=True)
/解码cf中的srv/conda/envs/notebook/lib/python3.7/site-packages/xarray/conventions.py
594 drop_变量=drop_变量,
595使用时间=使用时间,
-->596解码时间增量=解码时间增量,
597     )
598 ds=数据集(变量,属性=属性)
/解码cf_变量中的srv/conda/envs/notebook/lib/python3.7/site-packages/xarray/conventions.py
496堆栈字符尺寸=堆栈字符尺寸,
497使用时间=使用时间,
-->498解码时间增量=解码时间增量,
499         )
500如果解码协调:
/解码cf_变量中的srv/conda/envs/notebook/lib/python3.7/site-packages/xarray/conventions.py(名称、变量、concat_字符、掩码_和_比例、解码时间、解码结束时间、堆栈字符尺寸、使用时间、解码时间增量)
336 var=times.CFTimedeltaCoder().decode(var,name=name)
337如果解码\u次:
-->338 var=times.CFDatetimeCoder(use\u cftime=use\u cftime).decode(var,name=name)
339
340维、数据、属性、编码=变量。解包用于解码(var)
/解码中的srv/conda/envs/notebook/lib/python3.7/site-packages/xarray/coding/times.py(self、variable、name)
425个单位=pop_to(属性,编码,“单位”)
426 calendar=pop_to(属性,编码,“日历”)
-->427数据类型=\u解码\u cf\u日期时间\u数据类型(数据、单位、日历、自身使用时间)
428变换=部分(
429解码\u cf\u日期时间,
/srv/conda/envs/notebook/lib/python3.7/site-packages/xarray/coding/times.py in_decode_cf_datetime_dtype(数据、单位、日历、使用时间)
85“如果未安装。”
86         )
--->87提升值错误(msg)
88.其他:
89 dtype=getattr(结果,“dtype”,np.dtype(“对象”))
ValueError:无法使用“日历”“gregorian_proleptic”“”解码时间单位“自2016-01-01 00:00:00以来的天数”。尝试使用decode_times=False打开数据集,如果未安装,请安装cftime。

如果有用的话,这里是有问题的数据集中的。

还有另一个非坐标变量(
dstart
),它也得到了错误的
gregorian_proleptic
日历属性

如果设置正确:

ds.dstart.attrs['calendar']='proleptic_gregorian'
xr.decode_cf(ds, decode_times=True)

cf解码将起作用。

笔记本(jftr)中的“序言”中缺少一个t。还有,你有没有试着只解码时间坐标而不是整个数据集?@kmuehlbauer,我修正了输入错误,但这并不影响问题——你可以看到它仍然在寻找
gregorian_proleptic
,不管我指定什么!我只是通过查看几乎每个属性才发现这一点。如果xarray错误消息至少能命名中断的对象(在本例中是dstart
),那就容易多了。@kmuehlbaeur,哇,很棒的侦察!所以我想好消息是我使用的方法是