Skip to content

Commit 1ecb6e8

Browse files
dcherianfujiisoup
authored andcommitted
interp() now accepts date strings as desired co-ordinate locations (#2325)
* interp() now accepts date strings as desired co-ordinate locations Fixes #2284 * Consolidated tests. * Update condition for python 2 * Add additional test. * Add decorator.
1 parent f281945 commit 1ecb6e8

File tree

4 files changed

+38
-16
lines changed

4 files changed

+38
-16
lines changed

doc/interpolation.rst

+2-4
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,13 @@ array-like, which gives the interpolated result as an array.
4848
# interpolation
4949
da.interp(time=[2.5, 3.5])
5050
51-
52-
To interpolate data with a :py:func:`numpy.datetime64` coordinate you have to
53-
wrap it explicitly in a :py:func:`numpy.datetime64` object.
51+
To interpolate data with a :py:func:`numpy.datetime64` coordinate you can pass a string.
5452

5553
.. ipython:: python
5654
5755
da_dt64 = xr.DataArray([1, 3],
5856
[('time', pd.date_range('1/1/2000', '1/3/2000', periods=2))])
59-
da_dt64.interp(time=np.datetime64('2000-01-02'))
57+
da_dt64.interp(time='2000-01-02')
6058
6159
The interpolated data can be merged into the original :py:class:`~xarray.DataArray`
6260
by specifing the time periods required.

doc/whats-new.rst

+4
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ Enhancements
4141
(:issue:`1186`)
4242
By `Seth P <https://github.com/seth-p>`_.
4343

44+
- When interpolating over a ``datetime64`` axis, you can now provide a datetime string instead of a ``datetime64`` object. E.g. ``da.interp(time='1991-02-01')``
45+
(:issue:`2284`)
46+
By `Deepak Cherian <https://github.com/dcherian>`_.
47+
4448

4549
Bug fixes
4650
~~~~~~~~~

xarray/core/dataset.py

+8
Original file line numberDiff line numberDiff line change
@@ -1308,6 +1308,8 @@ def _validate_indexers(self, indexers):
13081308
""" Here we make sure
13091309
+ indexer has a valid keys
13101310
+ indexer is in a valid data type
1311+
* string indexers are cast to datetime64
1312+
if associated index is DatetimeIndex
13111313
"""
13121314
from .dataarray import DataArray
13131315

@@ -1328,6 +1330,12 @@ def _validate_indexers(self, indexers):
13281330
raise TypeError('cannot use a Dataset as an indexer')
13291331
else:
13301332
v = np.asarray(v)
1333+
1334+
if ((v.dtype.kind == 'U' or v.dtype.kind == 'S')
1335+
and isinstance(self.coords[k].to_index(),
1336+
pd.DatetimeIndex)):
1337+
v = v.astype('datetime64[ns]')
1338+
13311339
if v.ndim == 0:
13321340
v = as_variable(v)
13331341
elif v.ndim == 1:

xarray/tests/test_interp.py

+24-12
Original file line numberDiff line numberDiff line change
@@ -462,19 +462,31 @@ def test_interp_like():
462462

463463

464464
@requires_scipy
465-
def test_datetime():
466-
da = xr.DataArray(np.random.randn(24), dims='time',
465+
@pytest.mark.parametrize('x_new, expected', [
466+
(pd.date_range('2000-01-02', periods=3), [1, 2, 3]),
467+
(np.array([np.datetime64('2000-01-01T12:00'),
468+
np.datetime64('2000-01-02T12:00')]), [0.5, 1.5]),
469+
(['2000-01-01T12:00', '2000-01-02T12:00'], [0.5, 1.5]),
470+
(['2000-01-01T12:00'], 0.5),
471+
pytest.param('2000-01-01T12:00', 0.5, marks=pytest.mark.xfail)
472+
])
473+
def test_datetime(x_new, expected):
474+
da = xr.DataArray(np.arange(24), dims='time',
467475
coords={'time': pd.date_range('2000-01-01', periods=24)})
468476

469-
x_new = pd.date_range('2000-01-02', periods=3)
470477
actual = da.interp(time=x_new)
471-
expected = da.isel(time=[1, 2, 3])
472-
assert_allclose(actual, expected)
478+
expected_da = xr.DataArray(np.atleast_1d(expected), dims=['time'],
479+
coords={'time': (np.atleast_1d(x_new)
480+
.astype('datetime64[ns]'))})
473481

474-
x_new = np.array([np.datetime64('2000-01-01T12:00'),
475-
np.datetime64('2000-01-02T12:00')])
476-
actual = da.interp(time=x_new)
477-
assert_allclose(actual.isel(time=0).drop('time'),
478-
0.5 * (da.isel(time=0) + da.isel(time=1)))
479-
assert_allclose(actual.isel(time=1).drop('time'),
480-
0.5 * (da.isel(time=1) + da.isel(time=2)))
482+
assert_allclose(actual, expected_da)
483+
484+
485+
@requires_scipy
486+
def test_datetime_single_string():
487+
da = xr.DataArray(np.arange(24), dims='time',
488+
coords={'time': pd.date_range('2000-01-01', periods=24)})
489+
actual = da.interp(time='2000-01-01T12:00')
490+
expected = xr.DataArray(0.5)
491+
492+
assert_allclose(actual.drop('time'), expected)

0 commit comments

Comments
 (0)