From 2687e34e603e3747f94af35be0391d331e6cc2ca Mon Sep 17 00:00:00 2001 From: Spencer Clark Date: Sun, 22 Mar 2020 10:48:19 -0400 Subject: [PATCH 01/15] Possible _get_nearest_indexer fix --- ci/deps/travis-36-cov.yaml | 1 + pandas/core/indexes/base.py | 5 +++-- pandas/core/indexes/datetimelike.py | 23 +++++++++++++++++++++++ pandas/tests/test_downstream.py | 12 ++++++++++++ 4 files changed, 39 insertions(+), 2 deletions(-) diff --git a/ci/deps/travis-36-cov.yaml b/ci/deps/travis-36-cov.yaml index 6883301a63a9b..35f8a37524030 100644 --- a/ci/deps/travis-36-cov.yaml +++ b/ci/deps/travis-36-cov.yaml @@ -15,6 +15,7 @@ dependencies: # pandas dependencies - beautifulsoup4 - botocore>=1.11 + - cftime - cython>=0.29.13 - dask - fastparquet>=0.3.2 diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 83064fe22eaff..6aaeb9e88f9d7 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -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( diff --git a/pandas/core/indexes/datetimelike.py b/pandas/core/indexes/datetimelike.py index 25333b3a08dce..0e6bb2f3f0a17 100644 --- a/pandas/core/indexes/datetimelike.py +++ b/pandas/core/indexes/datetimelike.py @@ -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 @@ -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 diff --git a/pandas/tests/test_downstream.py b/pandas/tests/test_downstream.py index 122ef1f47968e..117be35bbcdec 100644 --- a/pandas/tests/test_downstream.py +++ b/pandas/tests/test_downstream.py @@ -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"]) From 7b4458d67fdcd570f2e6112921784a28af702960 Mon Sep 17 00:00:00 2001 From: Spencer Clark Date: Sun, 22 Mar 2020 11:13:32 -0400 Subject: [PATCH 02/15] isort --- pandas/core/indexes/datetimelike.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/indexes/datetimelike.py b/pandas/core/indexes/datetimelike.py index 0e6bb2f3f0a17..8f1ec107e4040 100644 --- a/pandas/core/indexes/datetimelike.py +++ b/pandas/core/indexes/datetimelike.py @@ -1,8 +1,8 @@ """ Base and utility classes for tseries type pandas objects. """ -import operator from datetime import datetime +import operator from typing import Any, List, Optional, Union import numpy as np From 59982955a728250a1f719f9c372faaaa9d243527 Mon Sep 17 00:00:00 2001 From: Spencer Clark Date: Sun, 22 Mar 2020 16:36:20 -0400 Subject: [PATCH 03/15] Address initial review comments --- ci/deps/azure-36-locale.yaml | 1 + ci/deps/azure-37-locale.yaml | 1 + ci/deps/azure-macos-36.yaml | 1 + pandas/core/indexes/base.py | 7 +++---- pandas/core/indexes/datetimelike.py | 22 ---------------------- pandas/tests/test_downstream.py | 4 ++-- 6 files changed, 8 insertions(+), 28 deletions(-) diff --git a/ci/deps/azure-36-locale.yaml b/ci/deps/azure-36-locale.yaml index 810554632a507..d3f256148e20f 100644 --- a/ci/deps/azure-36-locale.yaml +++ b/ci/deps/azure-36-locale.yaml @@ -15,6 +15,7 @@ dependencies: # pandas dependencies - beautifulsoup4 + - cftime - gcsfs - html5lib - ipython diff --git a/ci/deps/azure-37-locale.yaml b/ci/deps/azure-37-locale.yaml index dc51597a33209..642fde2e02a42 100644 --- a/ci/deps/azure-37-locale.yaml +++ b/ci/deps/azure-37-locale.yaml @@ -14,6 +14,7 @@ dependencies: # pandas dependencies - beautifulsoup4 + - cftime - html5lib - ipython - jinja2 diff --git a/ci/deps/azure-macos-36.yaml b/ci/deps/azure-macos-36.yaml index 90980133b31c1..d6695f312fa4f 100644 --- a/ci/deps/azure-macos-36.yaml +++ b/ci/deps/azure-macos-36.yaml @@ -14,6 +14,7 @@ dependencies: # pandas dependencies - beautifulsoup4 - bottleneck + - cftime - html5lib - jinja2 - lxml diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 6aaeb9e88f9d7..bb1e67911f305 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -3049,9 +3049,8 @@ 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) - target = np.asarray(target) - left_distances = np.abs(self.values[left_indexer] - target) - right_distances = np.abs(self.values[right_indexer] - target) + left_distances = np.abs(self._values[left_indexer] - target._values) + right_distances = np.abs(self._values[right_indexer] - target._values) op = operator.lt if self.is_monotonic_increasing else operator.le indexer = np.where( @@ -3060,7 +3059,7 @@ def _get_nearest_indexer(self, target: "Index", limit, tolerance) -> np.ndarray: right_indexer, ) if tolerance is not None: - indexer = self._filter_indexer_tolerance(target, indexer, tolerance) + indexer = self._filter_indexer_tolerance(target._values, indexer, tolerance) return indexer def _filter_indexer_tolerance( diff --git a/pandas/core/indexes/datetimelike.py b/pandas/core/indexes/datetimelike.py index 8f1ec107e4040..3af830f06a26f 100644 --- a/pandas/core/indexes/datetimelike.py +++ b/pandas/core/indexes/datetimelike.py @@ -958,25 +958,3 @@ 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 diff --git a/pandas/tests/test_downstream.py b/pandas/tests/test_downstream.py index 117be35bbcdec..9bfb60fb60ec4 100644 --- a/pandas/tests/test_downstream.py +++ b/pandas/tests/test_downstream.py @@ -49,8 +49,8 @@ def test_xarray(df): def test_xarray_cftimeindex_nearest(): # https://github.com/pydata/xarray/issues/3751 - cftime = import_module("cftime") # noqa - xarray = import_module("xarray") # noqa + cftime = import_module("cftime") + xarray = import_module("xarray") times = xarray.cftime_range("0001", periods=2) da = xarray.DataArray(range(2), coords=[("time", times)]) From 97bfabe6b0802bfe6f474c5818e8d6c24a2de0f0 Mon Sep 17 00:00:00 2001 From: Spencer Clark Date: Sun, 22 Mar 2020 16:42:49 -0400 Subject: [PATCH 04/15] target = target._values --- pandas/core/indexes/base.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index bb1e67911f305..9be6208beb816 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -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._values[left_indexer] - target._values) - right_distances = np.abs(self._values[right_indexer] - target._values) + target = target._values + 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( @@ -3059,7 +3060,7 @@ def _get_nearest_indexer(self, target: "Index", limit, tolerance) -> np.ndarray: right_indexer, ) if tolerance is not None: - indexer = self._filter_indexer_tolerance(target._values, indexer, tolerance) + indexer = self._filter_indexer_tolerance(target, indexer, tolerance) return indexer def _filter_indexer_tolerance( From 8034e559b6930e755b721b1a8bacd1568a5a5742 Mon Sep 17 00:00:00 2001 From: Spencer Clark Date: Sun, 22 Mar 2020 16:57:54 -0400 Subject: [PATCH 05/15] Add comments to environment yaml files --- ci/deps/azure-36-locale.yaml | 2 +- ci/deps/azure-37-locale.yaml | 2 +- ci/deps/azure-macos-36.yaml | 2 +- ci/deps/travis-36-cov.yaml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ci/deps/azure-36-locale.yaml b/ci/deps/azure-36-locale.yaml index d3f256148e20f..7abc4218fb577 100644 --- a/ci/deps/azure-36-locale.yaml +++ b/ci/deps/azure-36-locale.yaml @@ -15,7 +15,7 @@ dependencies: # pandas dependencies - beautifulsoup4 - - cftime + - cftime # Needed for downstream xarray.CFTimeIndex test - gcsfs - html5lib - ipython diff --git a/ci/deps/azure-37-locale.yaml b/ci/deps/azure-37-locale.yaml index 642fde2e02a42..a1330fe19d45b 100644 --- a/ci/deps/azure-37-locale.yaml +++ b/ci/deps/azure-37-locale.yaml @@ -14,7 +14,7 @@ dependencies: # pandas dependencies - beautifulsoup4 - - cftime + - cftime # Needed for downstream xarray.CFTimeIndex test - html5lib - ipython - jinja2 diff --git a/ci/deps/azure-macos-36.yaml b/ci/deps/azure-macos-36.yaml index d6695f312fa4f..01e2024ccd623 100644 --- a/ci/deps/azure-macos-36.yaml +++ b/ci/deps/azure-macos-36.yaml @@ -14,7 +14,7 @@ dependencies: # pandas dependencies - beautifulsoup4 - bottleneck - - cftime + - cftime # Needed for downstream xarray.CFTimeIndex test - html5lib - jinja2 - lxml diff --git a/ci/deps/travis-36-cov.yaml b/ci/deps/travis-36-cov.yaml index 35f8a37524030..c0313f101d792 100644 --- a/ci/deps/travis-36-cov.yaml +++ b/ci/deps/travis-36-cov.yaml @@ -15,7 +15,7 @@ dependencies: # pandas dependencies - beautifulsoup4 - botocore>=1.11 - - cftime + - cftime # Needed for downstream xarray.CFTimeIndex test - cython>=0.29.13 - dask - fastparquet>=0.3.2 From 5abefa3afe6fc0790126ab34c2395eaef9d6c05f Mon Sep 17 00:00:00 2001 From: Spencer Clark Date: Sun, 22 Mar 2020 17:02:56 -0400 Subject: [PATCH 06/15] Remove unused import --- pandas/core/indexes/datetimelike.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pandas/core/indexes/datetimelike.py b/pandas/core/indexes/datetimelike.py index 3af830f06a26f..25333b3a08dce 100644 --- a/pandas/core/indexes/datetimelike.py +++ b/pandas/core/indexes/datetimelike.py @@ -2,7 +2,6 @@ Base and utility classes for tseries type pandas objects. """ from datetime import datetime -import operator from typing import Any, List, Optional, Union import numpy as np From fc2aebfb8a0b4b556d37db200162feb2e22ed629 Mon Sep 17 00:00:00 2001 From: Spencer Clark Date: Sun, 22 Mar 2020 17:18:08 -0400 Subject: [PATCH 07/15] Fix mypy error --- pandas/core/indexes/base.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 9be6208beb816..bb94993b20061 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -280,7 +280,7 @@ def _outer_indexer(self, left, right): # Constructors def __new__( - cls, data=None, dtype=None, copy=False, name=None, tupleize_cols=True, **kwargs, + cls, data=None, dtype=None, copy=False, name=None, tupleize_cols=True, **kwargs ) -> "Index": from pandas.core.indexes.range import RangeIndex @@ -3049,9 +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) - target = target._values - left_distances = np.abs(self._values[left_indexer] - target) - right_distances = np.abs(self._values[right_indexer] - target) + target_values = target._values + left_distances = np.abs(self._values[left_indexer] - target_values) + right_distances = np.abs(self._values[right_indexer] - target_values) op = operator.lt if self.is_monotonic_increasing else operator.le indexer = np.where( @@ -3060,11 +3060,14 @@ def _get_nearest_indexer(self, target: "Index", limit, tolerance) -> np.ndarray: right_indexer, ) if tolerance is not None: - indexer = self._filter_indexer_tolerance(target, indexer, tolerance) + indexer = self._filter_indexer_tolerance(target_values, indexer, tolerance) return indexer def _filter_indexer_tolerance( - self, target: "Index", indexer: np.ndarray, tolerance + self, + target: Union["Index", np.ndarray, ExtensionArray], + indexer: np.ndarray, + tolerance, ) -> np.ndarray: distance = abs(self.values[indexer] - target) indexer = np.where(distance <= tolerance, indexer, -1) From 063488acccb449d9d39444254673db22c270d29c Mon Sep 17 00:00:00 2001 From: Spencer Clark Date: Sun, 22 Mar 2020 19:02:04 -0400 Subject: [PATCH 08/15] Update _filter_indexer_tolerance and write a better test --- pandas/core/indexes/base.py | 9 +++------ pandas/tests/test_downstream.py | 9 ++++----- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index bb94993b20061..703324177e9c3 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -3060,16 +3060,13 @@ def _get_nearest_indexer(self, target: "Index", limit, tolerance) -> np.ndarray: right_indexer, ) if tolerance is not None: - indexer = self._filter_indexer_tolerance(target_values, indexer, tolerance) + indexer = self._filter_indexer_tolerance(target, indexer, tolerance) return indexer def _filter_indexer_tolerance( - self, - target: Union["Index", np.ndarray, ExtensionArray], - indexer: np.ndarray, - tolerance, + self, target: "Index", indexer: np.ndarray, tolerance ) -> np.ndarray: - distance = abs(self.values[indexer] - target) + distance = abs(self.values._values[indexer] - target._values) indexer = np.where(distance <= tolerance, indexer, -1) return indexer diff --git a/pandas/tests/test_downstream.py b/pandas/tests/test_downstream.py index 9bfb60fb60ec4..a2b03d2869304 100644 --- a/pandas/tests/test_downstream.py +++ b/pandas/tests/test_downstream.py @@ -50,13 +50,12 @@ def test_xarray(df): def test_xarray_cftimeindex_nearest(): # https://github.com/pydata/xarray/issues/3751 cftime = import_module("cftime") - xarray = import_module("xarray") + 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) + result = times.get_loc(cftime.DatetimeGregorian(2000, 1, 1), method="nearest") + expected = 1 + assert result == expected def test_oo_optimizable(): From 2d4bc9b56e69b48769786e5bd4db6c7a22e505be Mon Sep 17 00:00:00 2001 From: Spencer Clark Date: Sun, 22 Mar 2020 19:03:20 -0400 Subject: [PATCH 09/15] Remove unneeded noqa again --- pandas/tests/test_downstream.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/test_downstream.py b/pandas/tests/test_downstream.py index a2b03d2869304..bf6b9dccdbdc1 100644 --- a/pandas/tests/test_downstream.py +++ b/pandas/tests/test_downstream.py @@ -50,7 +50,7 @@ def test_xarray(df): def test_xarray_cftimeindex_nearest(): # https://github.com/pydata/xarray/issues/3751 cftime = import_module("cftime") - xarray = import_module("xarray") # noqa + xarray = import_module("xarray") times = xarray.cftime_range("0001", periods=2) result = times.get_loc(cftime.DatetimeGregorian(2000, 1, 1), method="nearest") From 1c467c37f80ecf982df620d89a6c92f1952f60dd Mon Sep 17 00:00:00 2001 From: Spencer Clark Date: Sun, 22 Mar 2020 19:44:30 -0400 Subject: [PATCH 10/15] Fix typo --- pandas/core/indexes/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 703324177e9c3..67f657b12c6b4 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -3066,7 +3066,7 @@ def _get_nearest_indexer(self, target: "Index", limit, tolerance) -> np.ndarray: def _filter_indexer_tolerance( self, target: "Index", indexer: np.ndarray, tolerance ) -> np.ndarray: - distance = abs(self.values._values[indexer] - target._values) + distance = abs(self._values[indexer] - target._values) indexer = np.where(distance <= tolerance, indexer, -1) return indexer From addb4e10c01d1b9f8c185af390949c6465fb5a82 Mon Sep 17 00:00:00 2001 From: Spencer Clark Date: Mon, 23 Mar 2020 06:44:10 -0400 Subject: [PATCH 11/15] Revert back to previous _filter_indexer_tolerance solution --- pandas/core/indexes/base.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 67f657b12c6b4..0c4b5958c995f 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -280,7 +280,7 @@ def _outer_indexer(self, left, right): # Constructors def __new__( - cls, data=None, dtype=None, copy=False, name=None, tupleize_cols=True, **kwargs + cls, data=None, dtype=None, copy=False, name=None, tupleize_cols=True, **kwargs, ) -> "Index": from pandas.core.indexes.range import RangeIndex @@ -3060,13 +3060,16 @@ def _get_nearest_indexer(self, target: "Index", limit, tolerance) -> np.ndarray: right_indexer, ) if tolerance is not None: - indexer = self._filter_indexer_tolerance(target, indexer, tolerance) + indexer = self._filter_indexer_tolerance(target_values, indexer, tolerance) return indexer def _filter_indexer_tolerance( - self, target: "Index", indexer: np.ndarray, tolerance + self, + target: Union["Index", np.ndarray, ExtensionArray], + indexer: np.ndarray, + tolerance, ) -> np.ndarray: - distance = abs(self._values[indexer] - target._values) + distance = abs(self._values[indexer] - target) indexer = np.where(distance <= tolerance, indexer, -1) return indexer From 764439eb5d02d5f70d41c52e1bc8512152c7d0bb Mon Sep 17 00:00:00 2001 From: Spencer Clark Date: Mon, 23 Mar 2020 08:24:28 -0400 Subject: [PATCH 12/15] Move cftime to proper CI environment --- ci/deps/azure-36-locale.yaml | 1 - ci/deps/azure-37-locale.yaml | 1 - ci/deps/azure-macos-36.yaml | 1 - ci/deps/travis-36-cov.yaml | 1 - environment.yml | 1 + 5 files changed, 1 insertion(+), 4 deletions(-) diff --git a/ci/deps/azure-36-locale.yaml b/ci/deps/azure-36-locale.yaml index 7abc4218fb577..810554632a507 100644 --- a/ci/deps/azure-36-locale.yaml +++ b/ci/deps/azure-36-locale.yaml @@ -15,7 +15,6 @@ dependencies: # pandas dependencies - beautifulsoup4 - - cftime # Needed for downstream xarray.CFTimeIndex test - gcsfs - html5lib - ipython diff --git a/ci/deps/azure-37-locale.yaml b/ci/deps/azure-37-locale.yaml index a1330fe19d45b..dc51597a33209 100644 --- a/ci/deps/azure-37-locale.yaml +++ b/ci/deps/azure-37-locale.yaml @@ -14,7 +14,6 @@ dependencies: # pandas dependencies - beautifulsoup4 - - cftime # Needed for downstream xarray.CFTimeIndex test - html5lib - ipython - jinja2 diff --git a/ci/deps/azure-macos-36.yaml b/ci/deps/azure-macos-36.yaml index 01e2024ccd623..90980133b31c1 100644 --- a/ci/deps/azure-macos-36.yaml +++ b/ci/deps/azure-macos-36.yaml @@ -14,7 +14,6 @@ dependencies: # pandas dependencies - beautifulsoup4 - bottleneck - - cftime # Needed for downstream xarray.CFTimeIndex test - html5lib - jinja2 - lxml diff --git a/ci/deps/travis-36-cov.yaml b/ci/deps/travis-36-cov.yaml index c0313f101d792..6883301a63a9b 100644 --- a/ci/deps/travis-36-cov.yaml +++ b/ci/deps/travis-36-cov.yaml @@ -15,7 +15,6 @@ dependencies: # pandas dependencies - beautifulsoup4 - botocore>=1.11 - - cftime # Needed for downstream xarray.CFTimeIndex test - cython>=0.29.13 - dask - fastparquet>=0.3.2 diff --git a/environment.yml b/environment.yml index 532c36038fcaf..cf579738f6fe9 100644 --- a/environment.yml +++ b/environment.yml @@ -101,6 +101,7 @@ dependencies: - s3fs # pandas.read_csv... when using 's3://...' path - sqlalchemy # pandas.read_sql, DataFrame.to_sql - xarray # DataFrame.to_xarray + - cftime # Needed for downstream xarray.CFTimeIndex test - pyreadstat # pandas.read_spss - tabulate>=0.8.3 # DataFrame.to_markdown - pip: From c04fe3c2c9e1aae3fd0dc9a2d903e9d0e43a51e6 Mon Sep 17 00:00:00 2001 From: Spencer Clark Date: Mon, 23 Mar 2020 08:46:13 -0400 Subject: [PATCH 13/15] Use preferred pandas skipping logic; regenerate requirements-dev.txt --- pandas/tests/test_downstream.py | 8 ++++++-- requirements-dev.txt | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/pandas/tests/test_downstream.py b/pandas/tests/test_downstream.py index bf6b9dccdbdc1..57542aa3bc7f6 100644 --- a/pandas/tests/test_downstream.py +++ b/pandas/tests/test_downstream.py @@ -8,6 +8,8 @@ import numpy as np # noqa import pytest +import pandas.util._test_decorators as td + from pandas import DataFrame import pandas._testing as tm @@ -47,10 +49,12 @@ def test_xarray(df): assert df.to_xarray() is not None +@td.skip_if_no("cftime") +@td.skip_if_no("xarray", "0.10.4") def test_xarray_cftimeindex_nearest(): # https://github.com/pydata/xarray/issues/3751 - cftime = import_module("cftime") - xarray = import_module("xarray") + import cftime + import xarray times = xarray.cftime_range("0001", periods=2) result = times.get_loc(cftime.DatetimeGregorian(2000, 1, 1), method="nearest") diff --git a/requirements-dev.txt b/requirements-dev.txt index 9ee67c56ab8ca..6a2cc7b53615e 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -68,6 +68,7 @@ tables>=3.4.2 s3fs sqlalchemy xarray +cftime pyreadstat tabulate>=0.8.3 git+https://github.com/pandas-dev/pydata-sphinx-theme.git@master From 3c68605767c8415b015446b27daf604d30b7c8f3 Mon Sep 17 00:00:00 2001 From: Spencer Clark Date: Thu, 26 Mar 2020 07:00:31 -0400 Subject: [PATCH 14/15] Add a what's new entry --- doc/source/whatsnew/v1.1.0.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/source/whatsnew/v1.1.0.rst b/doc/source/whatsnew/v1.1.0.rst index 8cb80c7c92f8e..de4840609810e 100644 --- a/doc/source/whatsnew/v1.1.0.rst +++ b/doc/source/whatsnew/v1.1.0.rst @@ -310,6 +310,7 @@ Indexing - Bug in :meth:`DataFrame.iloc.__setitem__` on a :class:`DataFrame` with duplicate columns incorrectly setting values for all matching columns (:issue:`15686`, :issue:`22036`) - Bug in :meth:`DataFrame.loc:` and :meth:`Series.loc` with a :class:`DatetimeIndex`, :class:`TimedeltaIndex`, or :class:`PeriodIndex` incorrectly allowing lookups of non-matching datetime-like dtypes (:issue:`32650`) - Bug in :meth:`Series.__getitem__` indexing with non-standard scalars, e.g. ``np.dtype`` (:issue:`32684`) +- :meth:`Index._get_nearest_indexer` now internally uses NumPy arrays or ExtensionArrays to compute left and right distances. This preserves the fix to :issue:`26683` while maintaining compatibility with downstream :class:`Index` subclasses, e.g. xarray's CFTimeIndex (:issue:`32905`). See also `pydata/xarray#3751 `_. Missing ^^^^^^^ From b795f4c422ffd37d7cc8f99c49cee623e7a535a2 Mon Sep 17 00:00:00 2001 From: Spencer Clark Date: Thu, 26 Mar 2020 08:54:06 -0400 Subject: [PATCH 15/15] Remove reference to Index internals --- doc/source/whatsnew/v1.1.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v1.1.0.rst b/doc/source/whatsnew/v1.1.0.rst index de4840609810e..6983789989bb3 100644 --- a/doc/source/whatsnew/v1.1.0.rst +++ b/doc/source/whatsnew/v1.1.0.rst @@ -310,7 +310,7 @@ Indexing - Bug in :meth:`DataFrame.iloc.__setitem__` on a :class:`DataFrame` with duplicate columns incorrectly setting values for all matching columns (:issue:`15686`, :issue:`22036`) - Bug in :meth:`DataFrame.loc:` and :meth:`Series.loc` with a :class:`DatetimeIndex`, :class:`TimedeltaIndex`, or :class:`PeriodIndex` incorrectly allowing lookups of non-matching datetime-like dtypes (:issue:`32650`) - Bug in :meth:`Series.__getitem__` indexing with non-standard scalars, e.g. ``np.dtype`` (:issue:`32684`) -- :meth:`Index._get_nearest_indexer` now internally uses NumPy arrays or ExtensionArrays to compute left and right distances. This preserves the fix to :issue:`26683` while maintaining compatibility with downstream :class:`Index` subclasses, e.g. xarray's CFTimeIndex (:issue:`32905`). See also `pydata/xarray#3751 `_. +- Fix to preserve the ability to index with the "nearest" method with xarray's CFTimeIndex, an :class:`Index` subclass (`pydata/xarray#3751 `_, :issue:`32905`). Missing ^^^^^^^