Skip to content

Commit c52ff68

Browse files
toobazjreback
authored andcommitted
BUG: fix SparseSeries reindex by using Series implementation
closes pandas-dev#15447 Author: Pietro Battiston <[email protected]> Closes pandas-dev#15461 from toobaz/drop_sparse_reindex and squashes the following commits: 9084246 [Pietro Battiston] Test SparseSeries.reindex with fill_value and nearest d6a46da [Pietro Battiston] Use _shared_docs for documentation 922c7b0 [Pietro Battiston] Test "copy" argument af99190 [Pietro Battiston] Whatsnew 7945cb4 [Pietro Battiston] Tests for .loc() and .reindex() on sparse series with MultiIndex 55b99f8 [Pietro Battiston] BUG: Drop faulty and redundant reindex() for SparseSeries
1 parent a347ecb commit c52ff68

File tree

3 files changed

+61
-20
lines changed

3 files changed

+61
-20
lines changed

doc/source/whatsnew/v0.20.0.txt

+4
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,10 @@ Bug Fixes
672672
- Bug in ``Rolling.quantile`` function that caused a segmentation fault when called with a quantile value outside of the range [0, 1] (:issue:`15463`)
673673

674674

675+
- Bug in ``SparseSeries.reindex`` on single level with list of length 1 (:issue:`15447`)
676+
677+
678+
675679
- Bug in the display of ``.info()`` where a qualifier (+) would always be displayed with a ``MultiIndex`` that contains only non-strings (:issue:`15245`)
676680

677681
- Bug in ``.asfreq()``, where frequency was not set for empty ``Series` (:issue:`14320`)

pandas/sparse/series.py

+5-19
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
_coo_to_sparse_series)
3333

3434

35-
_shared_doc_kwargs = dict(klass='SparseSeries',
35+
_shared_doc_kwargs = dict(axes='index', klass='SparseSeries',
3636
axes_single_arg="{0, 'index'}")
3737

3838
# -----------------------------------------------------------------------------
@@ -570,27 +570,13 @@ def copy(self, deep=True):
570570
return self._constructor(new_data, sparse_index=self.sp_index,
571571
fill_value=self.fill_value).__finalize__(self)
572572

573+
@Appender(generic._shared_docs['reindex'] % _shared_doc_kwargs)
573574
def reindex(self, index=None, method=None, copy=True, limit=None,
574575
**kwargs):
575-
"""
576-
Conform SparseSeries to new Index
577-
578-
See Series.reindex docstring for general behavior
579576

580-
Returns
581-
-------
582-
reindexed : SparseSeries
583-
"""
584-
new_index = _ensure_index(index)
585-
586-
if self.index.equals(new_index):
587-
if copy:
588-
return self.copy()
589-
else:
590-
return self
591-
return self._constructor(self._data.reindex(new_index, method=method,
592-
limit=limit, copy=copy),
593-
index=new_index).__finalize__(self)
577+
return super(SparseSeries, self).reindex(index=index, method=method,
578+
copy=copy, limit=limit,
579+
**kwargs)
594580

595581
def sparse_reindex(self, new_index):
596582
"""

pandas/tests/sparse/test_indexing.py

+52-1
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ def test_reindex(self):
366366
exp = orig.reindex(['A', 'E', 'C', 'D']).to_sparse()
367367
tm.assert_sp_series_equal(res, exp)
368368

369-
def test_reindex_fill_value(self):
369+
def test_fill_value_reindex(self):
370370
orig = pd.Series([1, np.nan, 0, 3, 0], index=list('ABCDE'))
371371
sparse = orig.to_sparse(fill_value=0)
372372

@@ -397,6 +397,23 @@ def test_reindex_fill_value(self):
397397
exp = orig.reindex(['A', 'E', 'C', 'D']).to_sparse(fill_value=0)
398398
tm.assert_sp_series_equal(res, exp)
399399

400+
def test_reindex_fill_value(self):
401+
floats = pd.Series([1., 2., 3.]).to_sparse()
402+
result = floats.reindex([1, 2, 3], fill_value=0)
403+
expected = pd.Series([2., 3., 0], index=[1, 2, 3]).to_sparse()
404+
tm.assert_sp_series_equal(result, expected)
405+
406+
def test_reindex_nearest(self):
407+
s = pd.Series(np.arange(10, dtype='float64')).to_sparse()
408+
target = [0.1, 0.9, 1.5, 2.0]
409+
actual = s.reindex(target, method='nearest')
410+
expected = pd.Series(np.around(target), target).to_sparse()
411+
tm.assert_sp_series_equal(expected, actual)
412+
413+
actual = s.reindex(target, method='nearest', tolerance=0.2)
414+
expected = pd.Series([0, 1, np.nan, 2], target).to_sparse()
415+
tm.assert_sp_series_equal(expected, actual)
416+
400417
def tests_indexing_with_sparse(self):
401418
# GH 13985
402419

@@ -504,6 +521,11 @@ def test_loc(self):
504521
exp = orig.loc[[1, 3, 4, 5]].to_sparse()
505522
tm.assert_sp_series_equal(result, exp)
506523

524+
# single element list (GH 15447)
525+
result = sparse.loc[['A']]
526+
exp = orig.loc[['A']].to_sparse()
527+
tm.assert_sp_series_equal(result, exp)
528+
507529
# dense array
508530
result = sparse.loc[orig % 2 == 1]
509531
exp = orig.loc[orig % 2 == 1].to_sparse()
@@ -537,6 +559,35 @@ def test_loc_slice(self):
537559
orig.loc['A':'B'].to_sparse())
538560
tm.assert_sp_series_equal(sparse.loc[:'B'], orig.loc[:'B'].to_sparse())
539561

562+
def test_reindex(self):
563+
# GH 15447
564+
orig = self.orig
565+
sparse = self.sparse
566+
567+
res = sparse.reindex([('A', 0), ('C', 1)])
568+
exp = orig.reindex([('A', 0), ('C', 1)]).to_sparse()
569+
tm.assert_sp_series_equal(res, exp)
570+
571+
# On specific level:
572+
res = sparse.reindex(['A', 'C', 'B'], level=0)
573+
exp = orig.reindex(['A', 'C', 'B'], level=0).to_sparse()
574+
tm.assert_sp_series_equal(res, exp)
575+
576+
# single element list (GH 15447)
577+
res = sparse.reindex(['A'], level=0)
578+
exp = orig.reindex(['A'], level=0).to_sparse()
579+
tm.assert_sp_series_equal(res, exp)
580+
581+
with tm.assertRaises(TypeError):
582+
# Incomplete keys are not accepted for reindexing:
583+
sparse.reindex(['A', 'C'])
584+
585+
# "copy" argument:
586+
res = sparse.reindex(sparse.index, copy=True)
587+
exp = orig.reindex(orig.index, copy=True).to_sparse()
588+
tm.assert_sp_series_equal(res, exp)
589+
self.assertIsNot(sparse, res)
590+
540591

541592
class TestSparseDataFrameIndexing(tm.TestCase):
542593

0 commit comments

Comments
 (0)