Skip to content
forked from pydata/xarray

Commit 26547d1

Browse files
Fix bug in computing means of cftime.datetime arrays (pydata#4344)
1 parent e6c1113 commit 26547d1

File tree

3 files changed

+38
-2
lines changed

3 files changed

+38
-2
lines changed

doc/whats-new.rst

+2
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ Bug fixes
5757
`Sam Morley <https://github.com/inakleinbottle>`_.
5858
- Fixed inconsistencies between docstring and functionality for :py:meth:`DataArray.str.get`
5959
and :py:meth:`DataArray.str.wrap` (:issue:`4334`). By `Mathias Hauser <https://github.com/mathause>`_.
60+
- Fixed overflow issue causing incorrect results in computing means of :py:class:`cftime.datetime`
61+
arrays (:issue:`4341`). By `Spencer Clark <https://github.com/spencerkclark>`_.
6062

6163

6264
Documentation

xarray/core/duck_array_ops.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
accept or return xarray objects.
55
"""
66
import contextlib
7+
import datetime
78
import inspect
89
import warnings
910
from functools import partial
@@ -470,8 +471,7 @@ def timedelta_to_numeric(value, datetime_unit="ns", dtype=float):
470471

471472

472473
def _to_pytimedelta(array, unit="us"):
473-
index = pd.TimedeltaIndex(array.ravel(), unit=unit)
474-
return index.to_pytimedelta().reshape(array.shape)
474+
return array.astype(f"timedelta64[{unit}]").astype(datetime.timedelta)
475475

476476

477477
def np_timedelta64_to_float(array, datetime_unit):

xarray/tests/test_duck_array_ops.py

+34
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,40 @@ def test_cftime_datetime_mean():
333333
assert_equal(result, expected)
334334

335335

336+
@requires_cftime
337+
def test_cftime_datetime_mean_long_time_period():
338+
import cftime
339+
340+
times = np.array(
341+
[
342+
[
343+
cftime.DatetimeNoLeap(400, 12, 31, 0, 0, 0, 0),
344+
cftime.DatetimeNoLeap(520, 12, 31, 0, 0, 0, 0),
345+
],
346+
[
347+
cftime.DatetimeNoLeap(520, 12, 31, 0, 0, 0, 0),
348+
cftime.DatetimeNoLeap(640, 12, 31, 0, 0, 0, 0),
349+
],
350+
[
351+
cftime.DatetimeNoLeap(640, 12, 31, 0, 0, 0, 0),
352+
cftime.DatetimeNoLeap(760, 12, 31, 0, 0, 0, 0),
353+
],
354+
]
355+
)
356+
357+
da = DataArray(times, dims=["time", "d2"])
358+
result = da.mean("d2")
359+
expected = DataArray(
360+
[
361+
cftime.DatetimeNoLeap(460, 12, 31, 0, 0, 0, 0),
362+
cftime.DatetimeNoLeap(580, 12, 31, 0, 0, 0, 0),
363+
cftime.DatetimeNoLeap(700, 12, 31, 0, 0, 0, 0),
364+
],
365+
dims=["time"],
366+
)
367+
assert_equal(result, expected)
368+
369+
336370
@requires_cftime
337371
@requires_dask
338372
def test_cftime_datetime_mean_dask_error():

0 commit comments

Comments
 (0)