From 55b99f87ebfecc263f0bc2a4ec683e6863f150bf Mon Sep 17 00:00:00 2001 From: Pietro Battiston Date: Sat, 18 Feb 2017 04:13:30 +0100 Subject: [PATCH 1/6] BUG: Drop faulty and redundant reindex() for SparseSeries closes #15447 --- pandas/sparse/series.py | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/pandas/sparse/series.py b/pandas/sparse/series.py index dfdbb3c89814a..2d7be6d807919 100644 --- a/pandas/sparse/series.py +++ b/pandas/sparse/series.py @@ -570,8 +570,7 @@ def copy(self, deep=True): return self._constructor(new_data, sparse_index=self.sp_index, fill_value=self.fill_value).__finalize__(self) - def reindex(self, index=None, method=None, copy=True, limit=None, - **kwargs): + def reindex(self, index=None, **kwargs): """ Conform SparseSeries to new Index @@ -581,16 +580,7 @@ def reindex(self, index=None, method=None, copy=True, limit=None, ------- reindexed : SparseSeries """ - new_index = _ensure_index(index) - - if self.index.equals(new_index): - if copy: - return self.copy() - else: - return self - return self._constructor(self._data.reindex(new_index, method=method, - limit=limit, copy=copy), - index=new_index).__finalize__(self) + return super(SparseSeries, self).reindex(index, **kwargs) def sparse_reindex(self, new_index): """ From 7945cb48caec7c916778431c812102687eb51449 Mon Sep 17 00:00:00 2001 From: Pietro Battiston Date: Sat, 18 Feb 2017 04:59:00 +0100 Subject: [PATCH 2/6] Tests for .loc() and .reindex() on sparse series with MultiIndex --- pandas/tests/sparse/test_indexing.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/pandas/tests/sparse/test_indexing.py b/pandas/tests/sparse/test_indexing.py index 357a7103f4027..c71bf198d537a 100644 --- a/pandas/tests/sparse/test_indexing.py +++ b/pandas/tests/sparse/test_indexing.py @@ -504,6 +504,11 @@ def test_loc(self): exp = orig.loc[[1, 3, 4, 5]].to_sparse() tm.assert_sp_series_equal(result, exp) + # single element list (GH 15447) + result = sparse.loc[['A']] + exp = orig.loc[['A']].to_sparse() + tm.assert_sp_series_equal(result, exp) + # dense array result = sparse.loc[orig % 2 == 1] exp = orig.loc[orig % 2 == 1].to_sparse() @@ -537,6 +542,28 @@ def test_loc_slice(self): orig.loc['A':'B'].to_sparse()) tm.assert_sp_series_equal(sparse.loc[:'B'], orig.loc[:'B'].to_sparse()) + def test_reindex(self): + orig = self.orig + sparse = self.sparse + + res = sparse.reindex([('A', 0), ('C', 1)]) + exp = orig.reindex([('A', 0), ('C', 1)]).to_sparse() + tm.assert_sp_series_equal(res, exp) + + # On specific level: + res = sparse.reindex(['A', 'C', 'B'], level=0) + exp = orig.reindex(['A', 'C', 'B'], level=0).to_sparse() + tm.assert_sp_series_equal(res, exp) + + # single element list (GH 15447) + res = sparse.reindex(['A'], level=0) + exp = orig.reindex(['A'], level=0).to_sparse() + tm.assert_sp_series_equal(res, exp) + + with tm.assertRaises(TypeError): + # Incomplete keys are not accepted for reindexing: + sparse.reindex(['A', 'C']) + class TestSparseDataFrameIndexing(tm.TestCase): From af9919000ca042a2305939b630fcc420aa02d3b5 Mon Sep 17 00:00:00 2001 From: Pietro Battiston Date: Mon, 20 Feb 2017 19:32:30 +0100 Subject: [PATCH 3/6] Whatsnew --- doc/source/whatsnew/v0.20.0.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/source/whatsnew/v0.20.0.txt b/doc/source/whatsnew/v0.20.0.txt index c94429b469641..f0ee49b32d70c 100644 --- a/doc/source/whatsnew/v0.20.0.txt +++ b/doc/source/whatsnew/v0.20.0.txt @@ -542,6 +542,10 @@ Bug Fixes - Bug in ``Rolling.quantile`` function that caused a segmentation fault when called with a quantile value outside of the range [0, 1] (:issue:`15463`) +- Bug in ``SparseSeries.reindex`` on single level with list of length 1 (:issue:`15447`) + + + - Bug in the display of ``.info()`` where a qualifier (+) would always be displayed with a ``MultiIndex`` that contains only non-strings (:issue:`15245`) - Bug in ``pd.read_msgpack()`` in which ``Series`` categoricals were being improperly processed (:issue:`14901`) - Bug in ``Series.ffill()`` with mixed dtypes containing tz-aware datetimes. (:issue:`14956`) From 922c7b0947de7379348a38a8d2cebd9bd5d60ef4 Mon Sep 17 00:00:00 2001 From: Pietro Battiston Date: Sat, 25 Feb 2017 17:18:08 +0100 Subject: [PATCH 4/6] Test "copy" argument --- pandas/tests/sparse/test_indexing.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pandas/tests/sparse/test_indexing.py b/pandas/tests/sparse/test_indexing.py index c71bf198d537a..169a2772ee85a 100644 --- a/pandas/tests/sparse/test_indexing.py +++ b/pandas/tests/sparse/test_indexing.py @@ -543,6 +543,7 @@ def test_loc_slice(self): tm.assert_sp_series_equal(sparse.loc[:'B'], orig.loc[:'B'].to_sparse()) def test_reindex(self): + # GH 15447 orig = self.orig sparse = self.sparse @@ -564,6 +565,12 @@ def test_reindex(self): # Incomplete keys are not accepted for reindexing: sparse.reindex(['A', 'C']) + # "copy" argument: + res = sparse.reindex(sparse.index, copy=True) + exp = orig.reindex(orig.index, copy=True).to_sparse() + tm.assert_sp_series_equal(res, exp) + self.assertIsNot(sparse, res) + class TestSparseDataFrameIndexing(tm.TestCase): From d6a46dac32ac2268737fe12cfabcb83e3a2112d1 Mon Sep 17 00:00:00 2001 From: Pietro Battiston Date: Sat, 25 Feb 2017 17:18:51 +0100 Subject: [PATCH 5/6] Use _shared_docs for documentation --- pandas/sparse/series.py | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/pandas/sparse/series.py b/pandas/sparse/series.py index 2d7be6d807919..b4322487f8a9e 100644 --- a/pandas/sparse/series.py +++ b/pandas/sparse/series.py @@ -32,7 +32,7 @@ _coo_to_sparse_series) -_shared_doc_kwargs = dict(klass='SparseSeries', +_shared_doc_kwargs = dict(axes='index', klass='SparseSeries', axes_single_arg="{0, 'index'}") # ----------------------------------------------------------------------------- @@ -570,17 +570,13 @@ def copy(self, deep=True): return self._constructor(new_data, sparse_index=self.sp_index, fill_value=self.fill_value).__finalize__(self) - def reindex(self, index=None, **kwargs): - """ - Conform SparseSeries to new Index - - See Series.reindex docstring for general behavior + @Appender(generic._shared_docs['reindex'] % _shared_doc_kwargs) + def reindex(self, index=None, method=None, copy=True, limit=None, + **kwargs): - Returns - ------- - reindexed : SparseSeries - """ - return super(SparseSeries, self).reindex(index, **kwargs) + return super(SparseSeries, self).reindex(index=index, method=method, + copy=copy, limit=limit, + **kwargs) def sparse_reindex(self, new_index): """ From 9084246137277efcdcfc836744e4fca4c168a701 Mon Sep 17 00:00:00 2001 From: Pietro Battiston Date: Sat, 4 Mar 2017 16:50:19 +0100 Subject: [PATCH 6/6] Test SparseSeries.reindex with fill_value and nearest --- pandas/tests/sparse/test_indexing.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/pandas/tests/sparse/test_indexing.py b/pandas/tests/sparse/test_indexing.py index 169a2772ee85a..1a0782c0a3db9 100644 --- a/pandas/tests/sparse/test_indexing.py +++ b/pandas/tests/sparse/test_indexing.py @@ -366,7 +366,7 @@ def test_reindex(self): exp = orig.reindex(['A', 'E', 'C', 'D']).to_sparse() tm.assert_sp_series_equal(res, exp) - def test_reindex_fill_value(self): + def test_fill_value_reindex(self): orig = pd.Series([1, np.nan, 0, 3, 0], index=list('ABCDE')) sparse = orig.to_sparse(fill_value=0) @@ -397,6 +397,23 @@ def test_reindex_fill_value(self): exp = orig.reindex(['A', 'E', 'C', 'D']).to_sparse(fill_value=0) tm.assert_sp_series_equal(res, exp) + def test_reindex_fill_value(self): + floats = pd.Series([1., 2., 3.]).to_sparse() + result = floats.reindex([1, 2, 3], fill_value=0) + expected = pd.Series([2., 3., 0], index=[1, 2, 3]).to_sparse() + tm.assert_sp_series_equal(result, expected) + + def test_reindex_nearest(self): + s = pd.Series(np.arange(10, dtype='float64')).to_sparse() + target = [0.1, 0.9, 1.5, 2.0] + actual = s.reindex(target, method='nearest') + expected = pd.Series(np.around(target), target).to_sparse() + tm.assert_sp_series_equal(expected, actual) + + actual = s.reindex(target, method='nearest', tolerance=0.2) + expected = pd.Series([0, 1, np.nan, 2], target).to_sparse() + tm.assert_sp_series_equal(expected, actual) + def tests_indexing_with_sparse(self): # GH 13985