From 42938304ceab5a4c942332c63baa89393b6199cc Mon Sep 17 00:00:00 2001 From: "D.S. McNeil" Date: Tue, 6 Jun 2017 22:43:19 -0400 Subject: [PATCH] BUG: Fix Series.get failure on missing NaN (#8569) --- doc/source/whatsnew/v0.20.3.txt | 2 +- pandas/core/indexes/numeric.py | 2 ++ pandas/tests/indexes/test_multi.py | 8 ++++++++ pandas/tests/indexes/test_numeric.py | 8 ++++++++ pandas/tests/series/test_indexing.py | 15 +++++++++++++++ 5 files changed, 34 insertions(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v0.20.3.txt b/doc/source/whatsnew/v0.20.3.txt index 2032209c4aa23..049737f948e17 100644 --- a/doc/source/whatsnew/v0.20.3.txt +++ b/doc/source/whatsnew/v0.20.3.txt @@ -48,7 +48,7 @@ Conversion Indexing ^^^^^^^^ - +- Bug in ``Float64Index`` causing an empty array instead of None to be returned from ``.get(np.nan)`` on a Series whose index did not contain any NaNs (:issue:`8569`) I/O ^^^ diff --git a/pandas/core/indexes/numeric.py b/pandas/core/indexes/numeric.py index bdae0ac7ac5e9..72d521cbe2d60 100644 --- a/pandas/core/indexes/numeric.py +++ b/pandas/core/indexes/numeric.py @@ -369,6 +369,8 @@ def get_loc(self, key, method=None, tolerance=None): except (ValueError, IndexError): # should only need to catch ValueError here but on numpy # 1.7 .item() can raise IndexError when NaNs are present + if not len(nan_idxs): + raise KeyError(key) return nan_idxs except (TypeError, NotImplementedError): pass diff --git a/pandas/tests/indexes/test_multi.py b/pandas/tests/indexes/test_multi.py index ba917f33d8595..7d2e6f495311f 100644 --- a/pandas/tests/indexes/test_multi.py +++ b/pandas/tests/indexes/test_multi.py @@ -1172,6 +1172,14 @@ def test_get_loc_level(self): assert result == expected assert new_index.equals(index.droplevel(0)) + def test_get_loc_missing_nan(self): + # GH 8569 + idx = MultiIndex.from_arrays([[1.0, 2.0], [3.0, 4.0]]) + assert isinstance(idx.get_loc(1), slice) + pytest.raises(KeyError, idx.get_loc, 3) + pytest.raises(KeyError, idx.get_loc, np.nan) + pytest.raises(KeyError, idx.get_loc, [np.nan]) + def test_slice_locs(self): df = tm.makeTimeDataFrame() stacked = df.stack() diff --git a/pandas/tests/indexes/test_numeric.py b/pandas/tests/indexes/test_numeric.py index 29d4214fd549b..62ac337d02727 100644 --- a/pandas/tests/indexes/test_numeric.py +++ b/pandas/tests/indexes/test_numeric.py @@ -371,6 +371,14 @@ def test_get_loc_na(self): assert idx.get_loc(1) == 1 pytest.raises(KeyError, idx.slice_locs, np.nan) + def test_get_loc_missing_nan(self): + # GH 8569 + idx = Float64Index([1, 2]) + assert idx.get_loc(1) == 0 + pytest.raises(KeyError, idx.get_loc, 3) + pytest.raises(KeyError, idx.get_loc, np.nan) + pytest.raises(KeyError, idx.get_loc, [np.nan]) + def test_contains_nans(self): i = Float64Index([1.0, 2.0, np.nan]) assert np.nan in i diff --git a/pandas/tests/series/test_indexing.py b/pandas/tests/series/test_indexing.py index 6ded4d593a571..7774d10c5eaf8 100644 --- a/pandas/tests/series/test_indexing.py +++ b/pandas/tests/series/test_indexing.py @@ -70,6 +70,21 @@ def test_get(self): result = vc.get(True, default='Missing') assert result == 'Missing' + def test_get_nan(self): + # GH 8569 + s = pd.Float64Index(range(10)).to_series() + assert s.get(np.nan) is None + assert s.get(np.nan, default='Missing') == 'Missing' + + # ensure that fixing the above hasn't broken get + # with multiple elements + idx = [20, 30] + assert_series_equal(s.get(idx), + Series([np.nan] * 2, index=idx)) + idx = [np.nan, np.nan] + assert_series_equal(s.get(idx), + Series([np.nan] * 2, index=idx)) + def test_delitem(self): # GH 5542