Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
1 change: 1 addition & 0 deletions ci/deps/travis-36-cov.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ dependencies:
# pandas dependencies
- beautifulsoup4
- botocore>=1.11
- cftime
- cython>=0.29.13
- dask
- fastparquet>=0.3.2
Expand Down
5 changes: 3 additions & 2 deletions pandas/core/indexes/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3049,8 +3049,9 @@ def _get_nearest_indexer(self, target: "Index", limit, tolerance) -> np.ndarray:
left_indexer = self.get_indexer(target, "pad", limit=limit)
right_indexer = self.get_indexer(target, "backfill", limit=limit)

left_distances = np.abs(self[left_indexer] - target)
right_distances = np.abs(self[right_indexer] - target)
target = np.asarray(target)
left_distances = np.abs(self.values[left_indexer] - target)
right_distances = np.abs(self.values[right_indexer] - target)

op = operator.lt if self.is_monotonic_increasing else operator.le
indexer = np.where(
Expand Down
23 changes: 23 additions & 0 deletions pandas/core/indexes/datetimelike.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Base and utility classes for tseries type pandas objects.
"""
import operator
from datetime import datetime
from typing import Any, List, Optional, Union

Expand Down Expand Up @@ -957,3 +958,25 @@ def insert(self, loc, item):
raise TypeError(
f"cannot insert {type(self).__name__} with incompatible label"
) from err

def _get_nearest_indexer(self, target: "Index", limit, tolerance) -> np.ndarray:
"""
Get the indexer for the nearest index labels; requires an index with
values that can be subtracted from each other (e.g., not strings or
tuples).
"""
left_indexer = self.get_indexer(target, "pad", limit=limit)
right_indexer = self.get_indexer(target, "backfill", limit=limit)

left_distances = np.abs(self[left_indexer] - target)
right_distances = np.abs(self[right_indexer] - target)

op = operator.lt if self.is_monotonic_increasing else operator.le
indexer = np.where(
op(left_distances, right_distances) | (right_indexer == -1),
left_indexer,
right_indexer,
)
if tolerance is not None:
indexer = self._filter_indexer_tolerance(target, indexer, tolerance)
return indexer
12 changes: 12 additions & 0 deletions pandas/tests/test_downstream.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,18 @@ def test_xarray(df):
assert df.to_xarray() is not None


def test_xarray_cftimeindex_nearest():
# https://github.com/pydata/xarray/issues/3751
cftime = import_module("cftime") # noqa
xarray = import_module("xarray") # noqa

times = xarray.cftime_range("0001", periods=2)
da = xarray.DataArray(range(2), coords=[("time", times)])
result = da.sel(time=cftime.DatetimeGregorian(2000, 1, 1), method="nearest")
expected = xarray.DataArray(1, coords={"time": cftime.DatetimeGregorian(1, 1, 2)})
xarray.testing.assert_identical(result, expected)


def test_oo_optimizable():
# GH 21071
subprocess.check_call([sys.executable, "-OO", "-c", "import pandas"])
Expand Down