Skip to content

Commit 8ac61c5

Browse files
committed
BUG/ER: Stricter testing of 'monotocity' when reindexing with ffill or bfill (GH4483).
1 parent b364f91 commit 8ac61c5

File tree

6 files changed

+36
-8
lines changed

6 files changed

+36
-8
lines changed

doc/source/basics.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -724,16 +724,16 @@ We illustrate these fill methods on a simple TimeSeries:
724724
ts2.reindex(ts.index, method='ffill')
725725
ts2.reindex(ts.index, method='bfill')
726726
727+
Note these methods require that the indexes are **order increasing**.
728+
727729
Note the same result could have been achieved using :ref:`fillna
728730
<missing_data.fillna>`:
729731

730732
.. ipython:: python
731733
732734
ts2.reindex(ts.index).fillna(method='ffill')
733735
734-
Note these methods generally assume that the indexes are **sorted**. They may
735-
be modified in the future to be a bit more flexible but as time series data is
736-
ordered most of the time anyway, this has not been a major priority.
736+
Note that this method does not check the order of the index.
737737

738738
.. _basics.drop:
739739

doc/source/missing_data.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,9 @@ To remind you, these are the available filling methods:
205205
With time series data, using pad/ffill is extremely common so that the "last
206206
known value" is available at every time point.
207207

208+
The ``ffill()`` function is equivalent to ``fillna(method='ffill')``
209+
and ``bfill()`` is equivalent to ``fillna(method='bfill')``
210+
208211
.. _missing_data.dropna:
209212

210213
Dropping axis labels with missing data: dropna

doc/source/release.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ pandas 0.13
6262

6363
**API Changes**
6464

65+
- ``DataFrame.reindex()`` and forward/backward filling now raises ValueError
66+
if either index is not monotonic (:issue: `4483`, :issue: `4484`).
6567
- ``pandas`` now is Python 2/3 compatible without the need for 2to3 thanks to
6668
@jtratner. As a result, pandas now uses iterators more extensively. This
6769
also led to the introduction of substantive parts of the Benjamin

pandas/core/index.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -905,12 +905,12 @@ def get_indexer(self, target, method=None, limit=None):
905905
' valued Index objects')
906906

907907
if method == 'pad':
908-
if not self.is_monotonic:
909-
raise AssertionError('Must be monotonic for forward fill')
908+
if not self.is_monotonic or not target.is_monotonic:
909+
raise ValueError('Must be monotonic for forward fill')
910910
indexer = self._engine.get_pad_indexer(target.values, limit)
911911
elif method == 'backfill':
912-
if not self.is_monotonic:
913-
raise AssertionError('Must be monotonic for backward fill')
912+
if not self.is_monotonic or not target.is_monotonic:
913+
raise ValueError('Must be monotonic for backward fill')
914914
indexer = self._engine.get_backfill_indexer(target.values, limit)
915915
elif method is None:
916916
indexer = self._engine.get_indexer(target.values)

pandas/tests/test_frame.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1641,6 +1641,29 @@ def test_nested_exception(self):
16411641
except Exception as e:
16421642
self.assertNotEqual(type(e), UnboundLocalError)
16431643

1644+
def test_reverse_reindex_ffill_raises(self):
1645+
dr = pd.date_range('2013-08-01', periods=6, freq='B')
1646+
data = np.random.randn(6,1)
1647+
df = pd.DataFrame(data, index=dr, columns=list('A'))
1648+
df['A'][3] = np.nan
1649+
df_rev = pd.DataFrame(data, index=dr[::-1], columns=list('A'))
1650+
# Reverse index is not 'monotonic'
1651+
self.assertRaises(ValueError, df_rev.reindex, df.index, method='pad')
1652+
self.assertRaises(ValueError, df_rev.reindex, df.index, method='ffill')
1653+
self.assertRaises(ValueError, df_rev.reindex, df.index, method='bfill')
1654+
1655+
def test_reversed_reindex_ffill_raises(self):
1656+
dr = pd.date_range('2013-08-01', periods=6, freq='B')
1657+
data = np.random.randn(6,1)
1658+
df = pd.DataFrame(data, index=dr, columns=list('A'))
1659+
df['A'][3] = np.nan
1660+
df = pd.DataFrame(data, index=dr, columns=list('A'))
1661+
# Reversed reindex is not 'monotonic'
1662+
self.assertRaises(ValueError, df.reindex, dr[::-1], method='pad')
1663+
self.assertRaises(ValueError, df.reindex, dr[::-1], method='ffill')
1664+
self.assertRaises(ValueError, df.reindex, dr[::-1], method='bfill')
1665+
1666+
16441667
_seriesd = tm.getSeriesData()
16451668
_tsd = tm.getTimeSeriesData()
16461669

pandas/tseries/tests/test_timeseries.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,7 @@ def test_pad_require_monotonicity(self):
546546

547547
rng2 = rng[::2][::-1]
548548

549-
self.assertRaises(AssertionError, rng2.get_indexer, rng,
549+
self.assertRaises(ValueError, rng2.get_indexer, rng,
550550
method='pad')
551551

552552
def test_frame_ctor_datetime64_column(self):

0 commit comments

Comments
 (0)