Skip to content
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

ignore datetime units #241

Merged
merged 7 commits into from
Jan 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion docs/whats-new.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ What's new
0.4 (*unreleased*)
------------------
- adopt `SPEC0 <https://scientific-python.org/specs/spec-0000>`_ (:pull:`228`)
By `Justus Magin <https://github.com/keewis>`_.

This means that the supported versions change:

Expand All @@ -18,8 +17,11 @@ What's new
pint 0.16 0.19
============ ============== ==============

By `Justus Magin <https://github.com/keewis>`_.
- add support for python 3.11 (:pull:`228`)
By `Justus Magin <https://github.com/keewis>`_.
- ignore datetime units on attributes (:pull:`241`)
By `Justus Magin <https://github.com/keewis>`_.

0.3 (27 Jul 2022)
-----------------
Expand Down
12 changes: 12 additions & 0 deletions pint_xarray/accessors.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,12 @@ def quantify(self, units=_default, unit_registry=None, **unit_kwargs):
``xarray`` changes the way it implements indexes, these
units will be set as attributes.

.. note::
Also note that datetime units (i.e. ones that match
``{units} since {date}``) in unit attributes will be
ignored, to avoid interfering with ``xarray``'s datetime
encoding / decoding.

Parameters
----------
units : unit-like or mapping of hashable to unit-like, optional
Expand Down Expand Up @@ -984,6 +990,12 @@ def quantify(self, units=_default, unit_registry=None, **unit_kwargs):
``xarray`` changes the way it implements indexes, these
units will be set as attributes.

.. note::
Also note that datetime units (i.e. ones that match
``{units} since {date}``) in unit attributes will be
ignored, to avoid interfering with ``xarray``'s datetime
encoding / decoding.

Parameters
----------
units : mapping of hashable to unit-like, optional
Expand Down
18 changes: 17 additions & 1 deletion pint_xarray/conversion.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import itertools
import re

import pint
from xarray import DataArray, Dataset, IndexVariable, Variable
Expand All @@ -11,6 +12,14 @@
slice_attributes = ("start", "stop", "step")
temporary_name = "<this-array>"

time_units_re = r"\w+"
datetime_re = r"\d{4}-\d{2}-\d{2}(?:[ T]\d{2}:\d{2}:\d{2}(?:\.\d+)?)?"
datetime_units_re = re.compile(rf"{time_units_re} since {datetime_re}")


def is_datetime_unit(unit):
return isinstance(unit, str) and datetime_units_re.match(unit) is not None


def array_attach_units(data, unit):
"""attach a unit to the data
Expand Down Expand Up @@ -266,7 +275,11 @@ def extract_units(obj):


def extract_unit_attributes_dataset(obj, attr="units"):
return {name: var.attrs.get(attr, None) for name, var in obj.variables.items()}
all_units = {name: var.attrs.get(attr, None) for name, var in obj.variables.items()}

return {
name: unit for name, unit in all_units.items() if not is_datetime_unit(unit)
}


def extract_unit_attributes(obj, attr="units"):
Expand Down Expand Up @@ -308,6 +321,9 @@ def strip_units(obj):
def strip_unit_attributes_dataset(obj, attr="units"):
new_obj = obj.copy()
for var in new_obj.variables.values():
if is_datetime_unit(var.attrs.get(attr, "")):
continue

var.attrs.pop(attr, None)

return new_obj
Expand Down
10 changes: 10 additions & 0 deletions pint_xarray/tests/test_conversion.py
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,11 @@ def test_extract_units(self, type, units):
{"a": "K", "b": "hPa", "x": "m", "u": "s"},
id="Dataset",
),
pytest.param(
Dataset(coords={"t": ("t", [], {"units": "seconds since 2000-01-01"})}),
{},
id="datetime_unit",
),
),
)
def test_extract_unit_attributes(self, obj, expected):
Expand Down Expand Up @@ -546,6 +551,11 @@ def test_strip_units(self, obj, expected):
{"a": "K", "b": "hPa", "x": "m", "u": "s"},
id="Dataset",
),
pytest.param(
Dataset(coords={"t": ("t", [], {"units": "seconds since 2000-01-01"})}),
{},
id="datetime_unit",
),
),
)
def test_strip_unit_attributes(self, obj, expected):
Expand Down