Skip to content

Commit e19b2eb

Browse files
committed
Merge pull request pandas-dev#6628 from jreback/fillna_limit
BUG: Bug in fillna with limit and value specified
2 parents 98f51f5 + 74fbfcb commit e19b2eb

File tree

6 files changed

+51
-7
lines changed

6 files changed

+51
-7
lines changed

doc/source/release.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ Bug Fixes
232232
- Bug in sql writing with mixed dtypes possibly leading to data loss (:issue:`6509`)
233233
- Bug in popping from a Series (:issue:`6600`)
234234
- Bug in ``iloc`` indexing when positional indexer matched Int64Index of corresponding axis no reordering happened (:issue:`6612`)
235-
235+
- Bug in ``fillna`` with ``limit`` and ``value`` specified
236236

237237
pandas 0.13.1
238238
-------------

pandas/core/generic.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2162,7 +2162,9 @@ def fillna(self, value=None, method=None, axis=0, inplace=False,
21622162
from pandas import Series
21632163
value = Series(value)
21642164

2165-
new_data = self._data.fillna(value=value, inplace=inplace,
2165+
new_data = self._data.fillna(value=value,
2166+
limit=limit,
2167+
inplace=inplace,
21662168
downcast=downcast)
21672169

21682170
elif isinstance(value, (dict, com.ABCSeries)):
@@ -2176,10 +2178,12 @@ def fillna(self, value=None, method=None, axis=0, inplace=False,
21762178
if k not in result:
21772179
continue
21782180
obj = result[k]
2179-
obj.fillna(v, inplace=True)
2181+
obj.fillna(v, limit=limit, inplace=True)
21802182
return result
21812183
else:
2182-
new_data = self._data.fillna(value=value, inplace=inplace,
2184+
new_data = self._data.fillna(value=value,
2185+
limit=limit,
2186+
inplace=inplace,
21832187
downcast=downcast)
21842188

21852189
if inplace:

pandas/core/internals.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -367,14 +367,19 @@ def apply(self, func, **kwargs):
367367
""" apply the function to my values; return a block if we are not one """
368368
return self.as_block(func(self.values))
369369

370-
def fillna(self, value, inplace=False, downcast=None):
370+
def fillna(self, value, limit=None, inplace=False, downcast=None):
371371
if not self._can_hold_na:
372372
if inplace:
373373
return [self]
374374
else:
375375
return [self.copy()]
376376

377377
mask = com.isnull(self.values)
378+
if limit is not None:
379+
if self.ndim > 2:
380+
raise NotImplementedError
381+
mask[mask.cumsum(self.ndim-1)>limit]=False
382+
378383
value = self._try_fill(value)
379384
blocks = self.putmask(mask, value, inplace=inplace)
380385
return self._maybe_downcast(blocks, downcast)
@@ -1680,11 +1685,18 @@ def _try_fill(self, value):
16801685
value = tslib.iNaT
16811686
return value
16821687

1683-
def fillna(self, value, inplace=False, downcast=None):
1688+
def fillna(self, value, limit=None,
1689+
inplace=False, downcast=None):
1690+
16841691
# straight putmask here
16851692
values = self.values if inplace else self.values.copy()
16861693
mask = com.isnull(self.values)
16871694
value = self._try_fill(value)
1695+
if limit is not None:
1696+
if self.ndim > 2:
1697+
raise NotImplementedError
1698+
mask[mask.cumsum(self.ndim-1)>limit]=False
1699+
16881700
np.putmask(values, mask, value)
16891701
return [self if inplace else
16901702
make_block(values, self.items, self.ref_items, fastpath=True)]
@@ -1889,8 +1901,10 @@ def interpolate(self, method='pad', axis=0, inplace=False,
18891901
self.values.to_dense(), method, axis, limit, fill_value)
18901902
return self.make_block(values, self.items, self.ref_items)
18911903

1892-
def fillna(self, value, inplace=False, downcast=None):
1904+
def fillna(self, value, limit=None, inplace=False, downcast=None):
18931905
# we may need to upcast our fill to match our dtype
1906+
if limit is not None:
1907+
raise NotImplementedError
18941908
if issubclass(self.dtype.type, np.floating):
18951909
value = float(value)
18961910
values = self.values if inplace else self.values.copy()

pandas/tests/test_frame.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7113,6 +7113,17 @@ def test_fillna(self):
71137113
df.fillna({ 2: 'foo' }, inplace=True)
71147114
assert_frame_equal(df, expected)
71157115

7116+
# limit and value
7117+
df = DataFrame(np.random.randn(10,3))
7118+
df.iloc[2:7,0] = np.nan
7119+
df.iloc[3:5,2] = np.nan
7120+
7121+
expected = df.copy()
7122+
expected.iloc[2,0] = 999
7123+
expected.iloc[3,2] = 999
7124+
result = df.fillna(999,limit=1)
7125+
assert_frame_equal(result, expected)
7126+
71167127
def test_fillna_dtype_conversion(self):
71177128
# make sure that fillna on an empty frame works
71187129
df = DataFrame(index=["A","B","C"], columns = [1,2,3,4,5])

pandas/tests/test_panel.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1322,6 +1322,11 @@ def test_fillna(self):
13221322
self.assertRaises(TypeError, self.panel.fillna, [1, 2])
13231323
self.assertRaises(TypeError, self.panel.fillna, (1, 2))
13241324

1325+
# limit not implemented when only value is specified
1326+
p = Panel(np.random.randn(3,4,5))
1327+
p.iloc[0:2,0:2,0:2] = np.nan
1328+
self.assertRaises(NotImplementedError, lambda : p.fillna(999,limit=1))
1329+
13251330
def test_ffill_bfill(self):
13261331
assert_panel_equal(self.panel.ffill(),
13271332
self.panel.fillna(method='ffill'))

pandas/tests/test_series.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2941,6 +2941,16 @@ def test_fillna(self):
29412941
expected = Series([0,0,2.], list('bac'))
29422942
assert_series_equal(result,expected)
29432943

2944+
# limit
2945+
s = Series(np.nan,index=[0,1,2])
2946+
result = s.fillna(999,limit=1)
2947+
expected = Series([999,np.nan,np.nan],index=[0,1,2])
2948+
assert_series_equal(result,expected)
2949+
2950+
result = s.fillna(999,limit=2)
2951+
expected = Series([999,999,np.nan],index=[0,1,2])
2952+
assert_series_equal(result,expected)
2953+
29442954
def test_fillna_bug(self):
29452955
x = Series([nan, 1., nan, 3., nan], ['z', 'a', 'b', 'c', 'd'])
29462956
filled = x.fillna(method='ffill')

0 commit comments

Comments
 (0)