From 470eeb5cb6593a15cce9fdc4227ca8c33d416df1 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 | 13 +++++++++++++ 5 files changed, 32 insertions(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v0.20.3.txt b/doc/source/whatsnew/v0.20.3.txt index 2032209c4aa232..049737f948e178 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 bdae0ac7ac5e93..72d521cbe2d60c 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 ba917f33d85953..7d2e6f495311f6 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 29d4214fd549b5..62ac337d027273 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 6ded4d593a571d..2c6c8c19b10945 100644 --- a/pandas/tests/series/test_indexing.py +++ b/pandas/tests/series/test_indexing.py @@ -70,6 +70,19 @@ 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 + assert_series_equal(s.get([20, 30]), + Series([np.nan]*2, index=[20, 30])) + assert_series_equal(s.get([np.nan]*2), + Series([np.nan]*2, index=[np.nan]*2)) + def test_delitem(self): # GH 5542