Skip to content

Commit 4fb4dc9

Browse files
committed
GH pandas-dev#14499 Panel.ffill ignores axis parameter and fill along axis=1
1 parent eb7bd99 commit 4fb4dc9

File tree

3 files changed

+82
-21
lines changed

3 files changed

+82
-21
lines changed

doc/source/whatsnew/v0.19.1.txt

+3-1
Original file line numberDiff line numberDiff line change
@@ -83,4 +83,6 @@ Bug Fixes
8383

8484

8585
- Bug in ``pd.pivot_table`` may raise ``TypeError`` or ``ValueError`` when ``index`` or ``columns``
86-
is not scalar and ``values`` is not specified (:issue:`14380`)
86+
is not scalar and ``values`` is not specified (:issue:`14380`)
87+
88+
- Bug in ``pd.Panel.ffill`` where ``axis`` was not propagated (:issue:`14499`)

pandas/core/generic.py

+34-19
Original file line numberDiff line numberDiff line change
@@ -3205,26 +3205,21 @@ def fillna(self, value=None, method=None, axis=None, inplace=False,
32053205
'you passed a "{0}"'.format(type(value).__name__))
32063206
self._consolidate_inplace()
32073207

3208-
# set the default here, so functions examining the signaure
3208+
# set the default here, so functions examining the signature
32093209
# can detect if something was set (e.g. in groupby) (GH9221)
32103210
if axis is None:
3211-
axis = 0
3211+
if self.ndim == 3:
3212+
axis = 1
3213+
else:
3214+
axis = 0
3215+
32123216
axis = self._get_axis_number(axis)
32133217
method = missing.clean_fill_method(method)
32143218

32153219
from pandas import DataFrame
32163220
if value is None:
32173221
if method is None:
32183222
raise ValueError('must specify a fill method or value')
3219-
if self._is_mixed_type and axis == 1:
3220-
if inplace:
3221-
raise NotImplementedError()
3222-
result = self.T.fillna(method=method, limit=limit).T
3223-
3224-
# need to downcast here because of all of the transposes
3225-
result._data = result._data.downcast()
3226-
3227-
return result
32283223

32293224
# > 3d
32303225
if self.ndim > 3:
@@ -3233,21 +3228,41 @@ def fillna(self, value=None, method=None, axis=None, inplace=False,
32333228

32343229
# 3d
32353230
elif self.ndim == 3:
3236-
32373231
# fill in 2d chunks
3238-
result = dict([(col, s.fillna(method=method, value=value))
3239-
for col, s in self.iteritems()])
3232+
if axis == 0:
3233+
frame = self.swapaxes(0, 1)
3234+
axis2d = 0
3235+
else:
3236+
frame = self
3237+
axis2d = axis - 1
3238+
result = dict([(col, s.fillna(method=method,
3239+
value=value,
3240+
axis=axis2d))
3241+
for col, s in frame.iteritems()])
32403242
new_obj = self._constructor.\
32413243
from_dict(result).__finalize__(self)
3244+
if axis == 0:
3245+
new_obj = new_obj.swapaxes(0, 1)
32423246
new_data = new_obj._data
32433247

32443248
else:
32453249
# 2d or less
3246-
method = missing.clean_fill_method(method)
3247-
new_data = self._data.interpolate(method=method, axis=axis,
3248-
limit=limit, inplace=inplace,
3249-
coerce=True,
3250-
downcast=downcast)
3250+
if self._is_mixed_type and axis == 1:
3251+
if inplace:
3252+
raise NotImplementedError()
3253+
result = self.T.fillna(method=method, limit=limit).T
3254+
3255+
# need to downcast here because of all of the transposes
3256+
result._data = result._data.downcast()
3257+
3258+
return result
3259+
else:
3260+
method = missing.clean_fill_method(method)
3261+
new_data = self._data.interpolate(method=method, axis=axis,
3262+
limit=limit,
3263+
inplace=inplace,
3264+
coerce=True,
3265+
downcast=downcast)
32513266
else:
32523267
if method is not None:
32533268
raise ValueError('cannot specify both a fill method and value')

pandas/tests/test_panel.py

+45-1
Original file line numberDiff line numberDiff line change
@@ -1475,7 +1475,7 @@ def test_fillna(self):
14751475

14761476
panel = self.panel.copy()
14771477
panel['str'] = 'foo'
1478-
1478+
print(panel)
14791479
filled = panel.fillna(method='backfill')
14801480
assert_frame_equal(filled['ItemA'],
14811481
panel['ItemA'].fillna(method='backfill'))
@@ -1519,6 +1519,50 @@ def test_ffill_bfill(self):
15191519
assert_panel_equal(self.panel.bfill(),
15201520
self.panel.fillna(method='bfill'))
15211521

1522+
def test_ffill_bfill_axis(self):
1523+
# GH 14499
1524+
a = Panel({
1525+
'a': np.arange(15, dtype=float).reshape((5, 3)),
1526+
'b': np.arange(15, 30, dtype=float).reshape((5, 3))
1527+
})
1528+
f0 = a.copy()
1529+
f1 = a.copy()
1530+
f2 = a.copy()
1531+
b0 = a.copy()
1532+
b1 = a.copy()
1533+
b2 = a.copy()
1534+
a['a'].loc[1, 1] = np.nan
1535+
f0['a'].loc[1, 1] = np.nan
1536+
f1['a'].loc[1, 1] = 1
1537+
f2['a'].loc[1, 1] = 3
1538+
b0['a'].loc[1, 1] = 19.0
1539+
b1['a'].loc[1, 1] = 7
1540+
b2['a'].loc[1, 1] = 5
1541+
1542+
# method='ffill'
1543+
# axis=0
1544+
assert_panel_equal(a.ffill(axis=0), f0)
1545+
1546+
# method='ffill'
1547+
# axis=1
1548+
assert_panel_equal(a.ffill(axis=1), f1)
1549+
1550+
# method='ffill'
1551+
# axis=2
1552+
assert_panel_equal(a.ffill(axis=2), f2)
1553+
1554+
# method='bfill'
1555+
# axis=1
1556+
assert_panel_equal(a.bfill(axis=0), b0)
1557+
1558+
# method='bfill'
1559+
# axis=1
1560+
assert_panel_equal(a.bfill(axis=1), b1)
1561+
1562+
# method='bfill'
1563+
# axis=2
1564+
assert_panel_equal(a.bfill(axis=2), b2)
1565+
15221566
def test_truncate_fillna_bug(self):
15231567
# #1823
15241568
result = self.panel.truncate(before=None, after=None, axis='items')

0 commit comments

Comments
 (0)