-
-
Notifications
You must be signed in to change notification settings - Fork 18.5k
GH #14499 Panel.ffill ignores axis parameter and fill along axis=1 #14528
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3262,26 +3262,21 @@ def fillna(self, value=None, method=None, axis=None, inplace=False, | |
'you passed a "{0}"'.format(type(value).__name__)) | ||
self._consolidate_inplace() | ||
|
||
# set the default here, so functions examining the signaure | ||
# set the default here, so functions examining the signature | ||
# can detect if something was set (e.g. in groupby) (GH9221) | ||
if axis is None: | ||
axis = 0 | ||
if self.ndim == 3: | ||
axis = 1 | ||
else: | ||
axis = 0 | ||
|
||
axis = self._get_axis_number(axis) | ||
method = missing.clean_fill_method(method) | ||
|
||
from pandas import DataFrame | ||
if value is None: | ||
if method is None: | ||
raise ValueError('must specify a fill method or value') | ||
if self._is_mixed_type and axis == 1: | ||
if inplace: | ||
raise NotImplementedError() | ||
result = self.T.fillna(method=method, limit=limit).T | ||
|
||
# need to downcast here because of all of the transposes | ||
result._data = result._data.downcast() | ||
|
||
return result | ||
|
||
# > 3d | ||
if self.ndim > 3: | ||
|
@@ -3290,21 +3285,41 @@ def fillna(self, value=None, method=None, axis=None, inplace=False, | |
|
||
# 3d | ||
elif self.ndim == 3: | ||
|
||
# fill in 2d chunks | ||
result = dict([(col, s.fillna(method=method, value=value)) | ||
for col, s in self.iteritems()]) | ||
if axis == 0: | ||
frame = self.swapaxes(0, 1) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Question (not too familiar with Panels): swapping the axes here can potentially cause dtypes to change? (ints upcast to float, or numeric upcast to object when you have mixed dtypes) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point. Let me check |
||
axis2d = 0 | ||
else: | ||
frame = self | ||
axis2d = axis - 1 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
result = dict([(col, s.fillna(method=method, | ||
value=value, | ||
axis=axis2d)) | ||
for col, s in frame.iteritems()]) | ||
new_obj = self._constructor.\ | ||
from_dict(result).__finalize__(self) | ||
if axis == 0: | ||
new_obj = new_obj.swapaxes(0, 1) | ||
new_data = new_obj._data | ||
|
||
else: | ||
# 2d or less | ||
method = missing.clean_fill_method(method) | ||
new_data = self._data.interpolate(method=method, axis=axis, | ||
limit=limit, inplace=inplace, | ||
coerce=True, | ||
downcast=downcast) | ||
if self._is_mixed_type and axis == 1: | ||
if inplace: | ||
raise NotImplementedError() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add a message to the |
||
result = self.T.fillna(method=method, limit=limit).T | ||
|
||
# need to downcast here because of all of the transposes | ||
result._data = result._data.downcast() | ||
|
||
return result | ||
else: | ||
method = missing.clean_fill_method(method) | ||
new_data = self._data.interpolate(method=method, axis=axis, | ||
limit=limit, | ||
inplace=inplace, | ||
coerce=True, | ||
downcast=downcast) | ||
else: | ||
if method is not None: | ||
raise ValueError('cannot specify both a fill method and value') | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1519,6 +1519,50 @@ def test_ffill_bfill(self): | |
assert_panel_equal(self.panel.bfill(), | ||
self.panel.fillna(method='bfill')) | ||
|
||
def test_ffill_bfill_axis(self): | ||
# GH 14499 | ||
a = Panel({ | ||
'a': np.arange(15, dtype=float).reshape((5, 3)), | ||
'b': np.arange(15, 30, dtype=float).reshape((5, 3)) | ||
}) | ||
f0 = a.copy() | ||
f1 = a.copy() | ||
f2 = a.copy() | ||
b0 = a.copy() | ||
b1 = a.copy() | ||
b2 = a.copy() | ||
a['a'].loc[1, 1] = np.nan | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. set using full |
||
f0['a'].loc[1, 1] = np.nan | ||
f1['a'].loc[1, 1] = 1 | ||
f2['a'].loc[1, 1] = 3 | ||
b0['a'].loc[1, 1] = 19.0 | ||
b1['a'].loc[1, 1] = 7 | ||
b2['a'].loc[1, 1] = 5 | ||
|
||
# method='ffill' | ||
# axis=0 | ||
assert_panel_equal(a.ffill(axis=0), f0) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. make these expected before each statement, e.g.
|
||
|
||
# method='ffill' | ||
# axis=1 | ||
assert_panel_equal(a.ffill(axis=1), f1) | ||
|
||
# method='ffill' | ||
# axis=2 | ||
assert_panel_equal(a.ffill(axis=2), f2) | ||
|
||
# method='bfill' | ||
# axis=1 | ||
assert_panel_equal(a.bfill(axis=0), b0) | ||
|
||
# method='bfill' | ||
# axis=1 | ||
assert_panel_equal(a.bfill(axis=1), b1) | ||
|
||
# method='bfill' | ||
# axis=2 | ||
assert_panel_equal(a.bfill(axis=2), b2) | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ideally also tests with a panel that has a non-numeric type as well (IOW, add a string to the above example); this should be a separate set of tests. |
||
def test_truncate_fillna_bug(self): | ||
# #1823 | ||
result = self.panel.truncate(before=None, after=None, axis='items') | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
axis = self._stat_axis_number
give the correct default