Skip to content
forked from pydata/xarray

Commit

Permalink
Merge branch 'main' into flox-preserve-dtype
Browse files Browse the repository at this point in the history
* main:
  Opt out of floor division for float dtype time encoding (pydata#9497)
  fixed formatting for whats-new (pydata#9493)
  • Loading branch information
dcherian committed Sep 17, 2024
2 parents 5c9f291 + ef42335 commit d2648bc
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 15 deletions.
10 changes: 7 additions & 3 deletions doc/whats-new.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ New Features
`Matt Savoie <https://github.com/flamingbear>`_,
`Stephan Hoyer <https://github.com/shoyer>`_ and
`Tom Nicholas <https://github.com/TomNicholas>`_.

- Added zarr backends for :py:func:`open_groups` (:issue:`9430`, :pull:`9469`).
By `Eni Awowale <https://github.com/eni-awowale>`_.

Breaking changes
~~~~~~~~~~~~~~~~
Expand All @@ -46,7 +47,10 @@ Bug fixes
- Make illegal path-like variable names when constructing a DataTree from a Dataset
(:issue:`9339`, :pull:`9378`)
By `Etienne Schalk <https://github.com/etienneschalk>`_.

- Fix bug when encoding times with missing values as floats in the case when
the non-missing times could in theory be encoded with integers
(:issue:`9488`, :pull:`9497`). By `Spencer Clark
<https://github.com/spencerkclark>`_.


Documentation
Expand Down Expand Up @@ -194,8 +198,8 @@ New Features
to return an object without ``attrs``. A ``deep`` parameter controls whether
variables' ``attrs`` are also dropped.
By `Maximilian Roos <https://github.com/max-sixty>`_. (:pull:`8288`)
- Added :py:func:`open_groups` for h5netcdf and netCDF4 backends (:issue:`9137`, :pull:`9243`).
By `Eni Awowale <https://github.com/eni-awowale>`_.
- Add `open_groups` method for unaligned datasets (:issue:`9137`, :pull:`9243`)

Breaking changes
~~~~~~~~~~~~~~~~
Expand Down
4 changes: 2 additions & 2 deletions xarray/coding/times.py
Original file line number Diff line number Diff line change
Expand Up @@ -771,7 +771,7 @@ def _eagerly_encode_cf_datetime(
# needed time delta to encode faithfully to int64
needed_time_delta = _time_units_to_timedelta64(needed_units)

floor_division = True
floor_division = np.issubdtype(dtype, np.integer) or dtype is None
if time_delta > needed_time_delta:
floor_division = False
if dtype is None:
Expand Down Expand Up @@ -892,7 +892,7 @@ def _eagerly_encode_cf_timedelta(
# needed time delta to encode faithfully to int64
needed_time_delta = _time_units_to_timedelta64(needed_units)

floor_division = True
floor_division = np.issubdtype(dtype, np.integer) or dtype is None
if time_delta > needed_time_delta:
floor_division = False
if dtype is None:
Expand Down
42 changes: 32 additions & 10 deletions xarray/tests/test_coding_times.py
Original file line number Diff line number Diff line change
Expand Up @@ -1383,24 +1383,46 @@ def test_roundtrip_timedelta64_nanosecond_precision_warning() -> None:
assert decoded_var.encoding["dtype"] == np.int64


def test_roundtrip_float_times() -> None:
# Regression test for GitHub issue #8271
fill_value = 20.0
times = [
np.datetime64("1970-01-01 00:00:00", "ns"),
np.datetime64("1970-01-01 06:00:00", "ns"),
np.datetime64("NaT", "ns"),
]
_TEST_ROUNDTRIP_FLOAT_TIMES_TESTS = {
"GH-8271": (
20.0,
np.array(
["1970-01-01 00:00:00", "1970-01-01 06:00:00", "NaT"],
dtype="datetime64[ns]",
),
"days since 1960-01-01",
np.array([3653, 3653.25, 20.0]),
),
"GH-9488-datetime64[ns]": (
1.0e20,
np.array(["2010-01-01 12:00:00", "NaT"], dtype="datetime64[ns]"),
"seconds since 2010-01-01",
np.array([43200, 1.0e20]),
),
"GH-9488-timedelta64[ns]": (
1.0e20,
np.array([1_000_000_000, "NaT"], dtype="timedelta64[ns]"),
"seconds",
np.array([1.0, 1.0e20]),
),
}


units = "days since 1960-01-01"
@pytest.mark.parametrize(
("fill_value", "times", "units", "encoded_values"),
_TEST_ROUNDTRIP_FLOAT_TIMES_TESTS.values(),
ids=_TEST_ROUNDTRIP_FLOAT_TIMES_TESTS.keys(),
)
def test_roundtrip_float_times(fill_value, times, units, encoded_values) -> None:
# Regression test for GitHub issues #8271 and #9488
var = Variable(
["time"],
times,
encoding=dict(dtype=np.float64, _FillValue=fill_value, units=units),
)

encoded_var = conventions.encode_cf_variable(var)
np.testing.assert_array_equal(encoded_var, np.array([3653, 3653.25, 20.0]))
np.testing.assert_array_equal(encoded_var, encoded_values)
assert encoded_var.attrs["units"] == units
assert encoded_var.attrs["_FillValue"] == fill_value

Expand Down

0 comments on commit d2648bc

Please sign in to comment.