-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Relax nanosecond datetime restriction in CF time decoding #9618
base: main
Are you sure you want to change the base?
Changes from all commits
7b5f323
8784f33
b45ab23
39086ef
df49a40
adb8ca3
266b1ed
6d5f13b
5d68bfe
07bba69
6e7f0bb
b4a49bb
2e1ff4f
d5a7da0
821b68d
d066edf
ed22da1
8bf23f4
c3a2b39
3c44aed
48be73a
7ac9983
d86ad04
b5d0795
60324f0
6f2861a
1f07500
798b444
f487599
20d6c9d
7391948
308091c
5f40b4e
2a65d8d
43f7d61
59934b9
a01f9f3
8b91128
0e351ca
07a8e9c
2be5739
b9d0a8e
08afc3b
edc55e1
bffe919
150b982
7113ceb
7f47f0b
512808d
63c83f4
0efbbeb
2910250
57d8d72
5333240
6f35c81
d0c17a4
b2b6bb1
5dbc8a7
be0d3e0
f95408a
609e15c
ec7f165
1f1cf1c
14b1a88
05627dd
e7cbf3a
fc87e04
9ae645e
6e3ca57
277d1c6
81a9d94
be8642f
f3f62e5
c07df41
9653a01
f5822fd
66c0b9f
ba51274
3ba3e3f
1ab43eb
45ba9d3
091a90d
ab3c9ed
53fe43a
a16a890
4283f8a
0ba848d
6cb8702
5de8d0d
fc985d9
799b750
941c4b5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,20 +21,31 @@ core functionality. | |
Creating datetime64 data | ||
------------------------ | ||
|
||
Xarray uses the numpy dtypes ``datetime64[ns]`` and ``timedelta64[ns]`` to | ||
represent datetime data, which offer vectorized (if sometimes buggy) operations | ||
with numpy and smooth integration with pandas. | ||
Xarray uses the numpy dtypes ``datetime64[unit]`` and ``timedelta64[unit]`` | ||
(where unit is one of "s", "ms", "us" and "ns") to represent datetime | ||
data, which offer vectorized operations with numpy and smooth integration with pandas. | ||
|
||
To convert to or create regular arrays of ``datetime64`` data, we recommend | ||
using :py:func:`pandas.to_datetime` and :py:func:`pandas.date_range`: | ||
|
||
.. ipython:: python | ||
|
||
pd.to_datetime(["2000-01-01", "2000-02-02"]) | ||
pd.DatetimeIndex( | ||
["2000-01-01 00:00:00", "2000-02-02 00:00:00"], dtype="datetime64[s]" | ||
) | ||
pd.date_range("2000-01-01", periods=365) | ||
pd.date_range("2000-01-01", periods=365, unit="s") | ||
|
||
.. note:: | ||
Care has to be taken to create the output with the wanted resolution. | ||
For :py:func:`pandas.date_range` the ``unit``-kwarg has to be specified | ||
and for :py:func:`pandas.to_datetime` the selection of the resolution | ||
isn't possible at all. For that :py:class:`pd.DatetimeIndex` can be used | ||
directly. | ||
|
||
Alternatively, you can supply arrays of Python ``datetime`` objects. These get | ||
converted automatically when used as arguments in xarray objects: | ||
converted automatically when used as arguments in xarray objects (with us-resolution): | ||
|
||
.. ipython:: python | ||
|
||
|
@@ -51,7 +62,7 @@ attribute like ``'days since 2000-01-01'``). | |
.. note:: | ||
|
||
When decoding/encoding datetimes for non-standard calendars or for dates | ||
before year 1678 or after year 2262, xarray uses the `cftime`_ library. | ||
before [1582-10-15](https://en.wikipedia.org/wiki/Gregorian_calendar), xarray uses the `cftime`_ library by default. | ||
It was previously packaged with the ``netcdf4-python`` package under the | ||
name ``netcdftime`` but is now distributed separately. ``cftime`` is an | ||
:ref:`optional dependency<installing>` of xarray. | ||
|
@@ -66,17 +77,15 @@ You can manual decode arrays in this form by passing a dataset to | |
|
||
attrs = {"units": "hours since 2000-01-01"} | ||
ds = xr.Dataset({"time": ("time", [0, 1, 2, 3], attrs)}) | ||
# Default decoding to 'ns'-resolution | ||
xr.decode_cf(ds) | ||
# Decoding to 's'-resolution | ||
coder = xr.coders.CFDatetimeCoder(time_unit="s") | ||
xr.decode_cf(ds, decode_times=coder) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👏 👏 |
||
|
||
One unfortunate limitation of using ``datetime64[ns]`` is that it limits the | ||
native representation of dates to those that fall between the years 1678 and | ||
2262. When a netCDF file contains dates outside of these bounds, dates will be | ||
returned as arrays of :py:class:`cftime.datetime` objects and a :py:class:`~xarray.CFTimeIndex` | ||
will be used for indexing. :py:class:`~xarray.CFTimeIndex` enables a subset of | ||
the indexing functionality of a :py:class:`pandas.DatetimeIndex` and is only | ||
fully compatible with the standalone version of ``cftime`` (not the version | ||
packaged with earlier versions ``netCDF4``). See :ref:`CFTimeIndex` for more | ||
information. | ||
From xarray TODO: version the resolution of the dates can be tuned between "s", "ms", "us" and "ns". One limitation of using ``datetime64[ns]`` is that it limits the native representation of dates to those that fall between the years 1678 and 2262, which gets increased significantly with lower resolutions. When a netCDF file contains dates outside of these bounds (or dates < 1582-10-15), dates will be returned as arrays of :py:class:`cftime.datetime` objects and a :py:class:`~xarray.CFTimeIndex` will be used for indexing. | ||
:py:class:`~xarray.CFTimeIndex` enables a subset of the indexing functionality of a :py:class:`pandas.DatetimeIndex`. | ||
See :ref:`CFTimeIndex` for more information. | ||
|
||
Datetime indexing | ||
----------------- | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,7 +10,7 @@ Weather and climate data | |
|
||
import xarray as xr | ||
|
||
Xarray can leverage metadata that follows the `Climate and Forecast (CF) conventions`_ if present. Examples include :ref:`automatic labelling of plots<plotting>` with descriptive names and units if proper metadata is present and support for non-standard calendars used in climate science through the ``cftime`` module(Explained in the :ref:`CFTimeIndex` section). There are also a number of :ref:`geosciences-focused projects that build on xarray<ecosystem>`. | ||
Xarray can leverage metadata that follows the `Climate and Forecast (CF) conventions`_ if present. Examples include :ref:`automatic labelling of plots<plotting>` with descriptive names and units if proper metadata is present and support for non-standard calendars used in climate science through the ``cftime`` module (explained in the :ref:`CFTimeIndex` section). There are also a number of :ref:`geosciences-focused projects that build on xarray<ecosystem>`. | ||
|
||
.. _Climate and Forecast (CF) conventions: https://cfconventions.org | ||
|
||
|
@@ -64,8 +64,7 @@ Through the standalone ``cftime`` library and a custom subclass of | |
:py:class:`pandas.Index`, xarray supports a subset of the indexing | ||
functionality enabled through the standard :py:class:`pandas.DatetimeIndex` for | ||
dates from non-standard calendars commonly used in climate science or dates | ||
using a standard calendar, but outside the `nanosecond-precision range`_ | ||
(approximately between years 1678 and 2262). | ||
using a standard calendar, but outside the `precision range`_ and dates [prior to 1582-10-15](https://en.wikipedia.org/wiki/Gregorian_calendar). | ||
|
||
.. note:: | ||
|
||
|
@@ -75,18 +74,14 @@ using a standard calendar, but outside the `nanosecond-precision range`_ | |
any of the following are true: | ||
|
||
- The dates are from a non-standard calendar | ||
- Any dates are outside the nanosecond-precision range. | ||
- Any dates are outside the nanosecond-precision range (prior xarray version 2024.11) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Todo: Fix version |
||
- Any dates are outside the time span limited by the resolution (from xarray version v2024.11) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TODO: Fix version |
||
|
||
Otherwise pandas-compatible dates from a standard calendar will be | ||
represented with the ``np.datetime64[ns]`` data type, enabling the use of a | ||
:py:class:`pandas.DatetimeIndex` or arrays with dtype ``np.datetime64[ns]`` | ||
and their full set of associated features. | ||
represented with the ``np.datetime64[unit]`` data type (where unit can be one of ["s", "ms", "us", "ns"], enabling the use of a :py:class:`pandas.DatetimeIndex` or arrays with dtype ``np.datetime64[unit]`` and their full set of associated features. | ||
|
||
As of pandas version 2.0.0, pandas supports non-nanosecond precision datetime | ||
values. For the time being, xarray still automatically casts datetime values | ||
to nanosecond-precision for backwards compatibility with older pandas | ||
versions; however, this is something we would like to relax going forward. | ||
See :issue:`7493` for more discussion. | ||
values. From xarray version 2024.11 the relaxed non-nanosecond precision datetime values will be used. | ||
|
||
For example, you can create a DataArray indexed by a time | ||
coordinate with dates from a no-leap calendar and a | ||
|
@@ -115,7 +110,7 @@ instance, we can create the same dates and DataArray we created above using: | |
Mirroring pandas' method with the same name, :py:meth:`~xarray.infer_freq` allows one to | ||
infer the sampling frequency of a :py:class:`~xarray.CFTimeIndex` or a 1-D | ||
:py:class:`~xarray.DataArray` containing cftime objects. It also works transparently with | ||
``np.datetime64[ns]`` and ``np.timedelta64[ns]`` data. | ||
``np.datetime64`` and ``np.timedelta64`` data (with "s", "ms", "us" or "ns" resolution). | ||
|
||
.. ipython:: python | ||
|
||
|
@@ -137,7 +132,7 @@ Conversion between non-standard calendar and to/from pandas DatetimeIndexes is | |
facilitated with the :py:meth:`xarray.Dataset.convert_calendar` method (also available as | ||
:py:meth:`xarray.DataArray.convert_calendar`). Here, like elsewhere in xarray, the ``use_cftime`` | ||
argument controls which datetime backend is used in the output. The default (``None``) is to | ||
use ``pandas`` when possible, i.e. when the calendar is standard and dates are within 1678 and 2262. | ||
use ``pandas`` when possible, i.e. when the calendar is ``standard``/``gregorian`` and dates [starting with 1582-10-15]((https://en.wikipedia.org/wiki/Gregorian_calendar)). There is no such restriction when converting to ``proleptic_gregorian`` calendar. | ||
|
||
.. ipython:: python | ||
|
||
|
@@ -241,6 +236,6 @@ For data indexed by a :py:class:`~xarray.CFTimeIndex` xarray currently supports: | |
|
||
da.resample(time="81min", closed="right", label="right", offset="3min").mean() | ||
|
||
.. _nanosecond-precision range: https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#timestamp-limitations | ||
.. _precision range: https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#timestamp-limitations | ||
.. _ISO 8601 standard: https://en.wikipedia.org/wiki/ISO_8601 | ||
.. _partial datetime string indexing: https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#partial-string-indexing |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
""" | ||
This module provides coder objects that encapsulate the | ||
"encoding/decoding" process. | ||
""" | ||
|
||
from xarray.coding.times import CFDatetimeCoder | ||
|
||
__all__ = [ | ||
"CFDatetimeCoder", | ||
] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we add an example with
xr.date_range
too please?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Honestly I might even just switch all of these to
xr.date_range