Skip to content

Commit 7512f95

Browse files
committed
Merge pull request #11124 from lmjohns3/master
BUG: Fix computation of invalid NaN indexes for interpolate.
2 parents 0c61168 + 9bc8e6f commit 7512f95

File tree

3 files changed

+25
-10
lines changed

3 files changed

+25
-10
lines changed

doc/source/whatsnew/v0.17.0.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@ Other enhancements
383383

384384
- ``DataFrame`` has gained the ``nlargest`` and ``nsmallest`` methods (:issue:`10393`)
385385

386-
- Add a ``limit_direction`` keyword argument that works with ``limit`` to enable ``interpolate`` to fill ``NaN`` values forward, backward, or both (:issue:`9218` and :issue:`10420`)
386+
- Add a ``limit_direction`` keyword argument that works with ``limit`` to enable ``interpolate`` to fill ``NaN`` values forward, backward, or both (:issue:`9218`, :issue:`10420`, :issue:`11115`)
387387

388388
.. ipython:: python
389389

pandas/core/common.py

+5-8
Original file line numberDiff line numberDiff line change
@@ -1582,13 +1582,10 @@ def interpolate_1d(xvalues, yvalues, method='linear', limit=None,
15821582
method = 'values'
15831583

15841584
def _interp_limit(invalid, fw_limit, bw_limit):
1585-
"Get idx of values that won't be forward-filled b/c they exceed the limit."
1586-
all_nans = np.where(invalid)[0]
1587-
if all_nans.size == 0: # no nans anyway
1588-
return []
1589-
violate = [invalid[max(0, x - bw_limit):x + fw_limit + 1] for x in all_nans]
1590-
violate = np.array([x.all() & (x.size > bw_limit + fw_limit) for x in violate])
1591-
return all_nans[violate] + fw_limit - bw_limit
1585+
"Get idx of values that won't be filled b/c they exceed the limits."
1586+
for x in np.where(invalid)[0]:
1587+
if invalid[max(0, x - fw_limit):x + bw_limit + 1].all():
1588+
yield x
15921589

15931590
valid_limit_directions = ['forward', 'backward', 'both']
15941591
limit_direction = limit_direction.lower()
@@ -1624,7 +1621,7 @@ def _interp_limit(invalid, fw_limit, bw_limit):
16241621
if limit_direction == 'backward':
16251622
violate_limit = sorted(end_nans | set(_interp_limit(invalid, 0, limit)))
16261623
if limit_direction == 'both':
1627-
violate_limit = _interp_limit(invalid, limit, limit)
1624+
violate_limit = sorted(_interp_limit(invalid, limit, limit))
16281625

16291626
xvalues = getattr(xvalues, 'values', xvalues)
16301627
yvalues = getattr(yvalues, 'values', yvalues)

pandas/tests/test_generic.py

+19-1
Original file line numberDiff line numberDiff line change
@@ -878,7 +878,6 @@ def test_interp_limit_forward(self):
878878

879879
def test_interp_limit_bad_direction(self):
880880
s = Series([1, 3, np.nan, np.nan, np.nan, 11])
881-
expected = Series([1., 3., 5., 7., 9., 11.])
882881

883882
self.assertRaises(ValueError, s.interpolate,
884883
method='linear', limit=2,
@@ -930,6 +929,25 @@ def test_interp_limit_to_ends(self):
930929
method='linear', limit=2, limit_direction='both')
931930
assert_series_equal(result, expected)
932931

932+
def test_interp_limit_before_ends(self):
933+
# These test are for issue #11115 -- limit ends properly.
934+
s = Series([np.nan, np.nan, 5, 7, np.nan, np.nan])
935+
936+
expected = Series([np.nan, np.nan, 5., 7., 7., np.nan])
937+
result = s.interpolate(
938+
method='linear', limit=1, limit_direction='forward')
939+
assert_series_equal(result, expected)
940+
941+
expected = Series([np.nan, 5., 5., 7., np.nan, np.nan])
942+
result = s.interpolate(
943+
method='linear', limit=1, limit_direction='backward')
944+
assert_series_equal(result, expected)
945+
946+
expected = Series([np.nan, 5., 5., 7., 7., np.nan])
947+
result = s.interpolate(
948+
method='linear', limit=1, limit_direction='both')
949+
assert_series_equal(result, expected)
950+
933951
def test_interp_all_good(self):
934952
# scipy
935953
tm._skip_if_no_scipy()

0 commit comments

Comments
 (0)