Да, я могу воспроизвести это. Это можно считать ошибкой в xarray; Вы можете рассмотреть вопрос о проблеме на GitHub .
При сохранении файла под капотом xarray берет декодированные даты и преобразует их в timedeltas, начиная с контрольной даты. Проблема в том, что даты в вашем примере набора данных пересекают границу на 292 года позже, чем указанная контрольная дата (1800-01-01).
In [1]: import numpy as np
In [2]: import xarray as xr
In [3]: ds = xr.Dataset(coords={'time': (
...: 'time',
...: np.arange(106300.5, 106665.5+5*365, 365),
...: {'units': 'days since 1800-01-01 00:00:00'})})
...:
In [4]: ds = xr.decode_cf(ds)
In [5]: ds.time
Out[5]:
<xarray.DataArray 'time' (time: 6)>
array(['2091-01-15T12:00:00.000000000', '2092-01-15T12:00:00.000000000',
'2093-01-14T12:00:00.000000000', '2094-01-14T12:00:00.000000000',
'2095-01-14T12:00:00.000000000', '2096-01-14T12:00:00.000000000'],
dtype='datetime64[ns]')
Coordinates:
* time (time) datetime64[ns] 2091-01-15T12:00:00 2092-01-15T12:00:00 ...
In [6]: ds.to_netcdf('so.nc')
In [7]: xr.open_dataset('so.nc', decode_times=False).time
so.nc
Out[7]:
<xarray.DataArray 'time' (time: 6)>
array([ 106300.5 , 106665.5 , -106473.482335, -106108.482335,
-105743.482335, -105378.482335])
Coordinates:
* time (time) float64 1.063e+05 1.067e+05 -1.065e+05 -1.061e+05 ...
Attributes:
units: days since 1800-01-01
calendar: proleptic_gregorian
292 года - максимальный отрезок времени, который может представлять np.timedelta64
объект с наносекундной точностью (см. здесь в документации); больше, чем это, и вы столкнетесь с переполнением (которое является причиной отрицательных значений).
Обходной путь, который вы можете использовать, - переписать кодировку единиц измерения, связанную с временем в вашем наборе данных, новым значением:
In [8]: ds.time.encoding['units'] = 'days since 1970-01-01'
In [9]: ds.to_netcdf('so-workaround.nc')
In [10]: xr.open_dataset('so-workaround.nc', decode_times=False).time
Out[10]:
<xarray.DataArray 'time' (time: 6)>
array([44209.5, 44574.5, 44939.5, 45304.5, 45669.5, 46034.5])
Coordinates:
* time (time) float64 4.421e+04 4.457e+04 4.494e+04 4.53e+04 4.567e+04 ...
Attributes:
units: days since 1970-01-01
calendar: proleptic_gregorian
Здесь я намеренно выбрал 'days since 1970-01-01'
, поскольку именно это np.datetime64
объектов сосредоточено вокруг NumPy.