Skip to content

Commit 2983c53

Browse files
Fix non-nanosecond casting behavior for expand_dims (#8782)
1 parent dfdd631 commit 2983c53

File tree

4 files changed

+35
-4
lines changed

4 files changed

+35
-4
lines changed

doc/whats-new.rst

+5
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ Bug fixes
4242
- The default ``freq`` parameter in :py:meth:`xr.date_range` and :py:meth:`xr.cftime_range` is
4343
set to ``'D'`` only if ``periods``, ``start``, or ``end`` are ``None`` (:issue:`8770`, :pull:`8774`).
4444
By `Roberto Chang <https://github.com/rjavierch>`_.
45+
- Ensure that non-nanosecond precision :py:class:`numpy.datetime64` and
46+
:py:class:`numpy.timedelta64` values are cast to nanosecond precision values
47+
when used in :py:meth:`DataArray.expand_dims` and
48+
::py:meth:`Dataset.expand_dims` (:pull:`8781`). By `Spencer
49+
Clark <https://github.com/spencerkclark>`_.
4550

4651
Documentation
4752
~~~~~~~~~~~~~

xarray/core/variable.py

+6-4
Original file line numberDiff line numberDiff line change
@@ -218,10 +218,12 @@ def _possibly_convert_datetime_or_timedelta_index(data):
218218
this in version 2.0.0, in xarray we will need to make sure we are ready to
219219
handle non-nanosecond precision datetimes or timedeltas in our code
220220
before allowing such values to pass through unchanged."""
221-
if isinstance(data, (pd.DatetimeIndex, pd.TimedeltaIndex)):
222-
return _as_nanosecond_precision(data)
223-
else:
224-
return data
221+
if isinstance(data, PandasIndexingAdapter):
222+
if isinstance(data.array, (pd.DatetimeIndex, pd.TimedeltaIndex)):
223+
data = PandasIndexingAdapter(_as_nanosecond_precision(data.array))
224+
elif isinstance(data, (pd.DatetimeIndex, pd.TimedeltaIndex)):
225+
data = _as_nanosecond_precision(data)
226+
return data
225227

226228

227229
def as_compatible_data(

xarray/tests/test_dataset.py

+8
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
requires_cupy,
6161
requires_dask,
6262
requires_numexpr,
63+
requires_pandas_version_two,
6364
requires_pint,
6465
requires_scipy,
6566
requires_sparse,
@@ -3446,6 +3447,13 @@ def test_expand_dims_kwargs_python36plus(self) -> None:
34463447
)
34473448
assert_identical(other_way_expected, other_way)
34483449

3450+
@requires_pandas_version_two
3451+
def test_expand_dims_non_nanosecond_conversion(self) -> None:
3452+
# Regression test for https://github.com/pydata/xarray/issues/7493#issuecomment-1953091000
3453+
with pytest.warns(UserWarning, match="non-nanosecond precision"):
3454+
ds = Dataset().expand_dims({"time": [np.datetime64("2018-01-01", "s")]})
3455+
assert ds.time.dtype == np.dtype("datetime64[ns]")
3456+
34493457
def test_set_index(self) -> None:
34503458
expected = create_test_multiindex()
34513459
mindex = expected["x"].to_index()

xarray/tests/test_variable.py

+16
Original file line numberDiff line numberDiff line change
@@ -3011,3 +3011,19 @@ def test_pandas_two_only_timedelta_conversion_warning() -> None:
30113011
var = Variable(["time"], data)
30123012

30133013
assert var.dtype == np.dtype("timedelta64[ns]")
3014+
3015+
3016+
@requires_pandas_version_two
3017+
@pytest.mark.parametrize(
3018+
("index", "dtype"),
3019+
[
3020+
(pd.date_range("2000", periods=1), "datetime64"),
3021+
(pd.timedelta_range("1", periods=1), "timedelta64"),
3022+
],
3023+
ids=lambda x: f"{x}",
3024+
)
3025+
def test_pandas_indexing_adapter_non_nanosecond_conversion(index, dtype) -> None:
3026+
data = PandasIndexingAdapter(index.astype(f"{dtype}[s]"))
3027+
with pytest.warns(UserWarning, match="non-nanosecond precision"):
3028+
var = Variable(["time"], data)
3029+
assert var.dtype == np.dtype(f"{dtype}[ns]")

0 commit comments

Comments
 (0)