Skip to content
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

Deprecate passing args as positional DataFrame/Series.ffill #41508

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/source/whatsnew/v1.3.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,7 @@ Deprecations
- Deprecated passing arguments as positional in :meth:`DataFrame.clip` and :meth:`Series.clip` (other than ``"upper"`` and ``"lower"``) (:issue:`41485`)
- Deprecated special treatment of lists with first element a Categorical in the :class:`DataFrame` constructor; pass as ``pd.DataFrame({col: categorical, ...})`` instead (:issue:`38845`)
- Deprecated passing arguments as positional (except for ``"method"``) in :meth:`DataFrame.interpolate` and :meth:`Series.interpolate` (:issue:`41485`)
- Deprecated passing arguments as positional in :meth:`DataFrame.ffill`, :meth:`Series.ffill`, :meth:`DataFrame.bfill`, and :meth:`Series.bfill` (:issue:`41485`)
- Deprecated passing arguments as positional in :meth:`DataFrame.sort_values` (other than ``"by"``) and :meth:`Series.sort_values` (:issue:`41485`)
- Deprecated passing arguments as positional in :meth:`DataFrame.dropna` and :meth:`Series.dropna` (:issue:`41485`)
- Deprecated passing arguments as positional in :meth:`DataFrame.set_index` (other than ``"keys"``) (:issue:`41485`)
Expand Down
20 changes: 20 additions & 0 deletions pandas/core/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -10646,6 +10646,26 @@ def values(self) -> np.ndarray:
self._consolidate_inplace()
return self._mgr.as_array(transpose=True)

@deprecate_nonkeyword_arguments(version=None, allowed_args=["self"])
def ffill(
self: DataFrame,
axis: None | Axis = None,
inplace: bool = False,
limit: None | int = None,
downcast=None,
) -> DataFrame | None:
return super().ffill(axis, inplace, limit, downcast)

@deprecate_nonkeyword_arguments(version=None, allowed_args=["self"])
def bfill(
self: DataFrame,
axis: None | Axis = None,
inplace: bool = False,
limit: None | int = None,
downcast=None,
) -> DataFrame | None:
return super().bfill(axis, inplace, limit, downcast)

@deprecate_nonkeyword_arguments(
version=None, allowed_args=["self", "lower", "upper"]
)
Expand Down
82 changes: 0 additions & 82 deletions pandas/core/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -6392,47 +6392,6 @@ def fillna(
else:
return result.__finalize__(self, method="fillna")

@overload
def ffill(
self: FrameOrSeries,
axis: None | Axis = ...,
inplace: Literal[False] = ...,
limit: None | int = ...,
downcast=...,
) -> FrameOrSeries:
Comment on lines -6395 to -6402
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will put the overloads back in once the FutureWarning's in, then we won't need as many

...

@overload
def ffill(
self: FrameOrSeries,
axis: None | Axis,
inplace: Literal[True],
limit: None | int = ...,
downcast=...,
) -> None:
...

@overload
def ffill(
self: FrameOrSeries,
*,
inplace: Literal[True],
limit: None | int = ...,
downcast=...,
) -> None:
...

@overload
def ffill(
self: FrameOrSeries,
axis: None | Axis = ...,
inplace: bool_t = ...,
limit: None | int = ...,
downcast=...,
) -> FrameOrSeries | None:
...

@final
@doc(klass=_shared_doc_kwargs["klass"])
def ffill(
self: FrameOrSeries,
Expand All @@ -6455,47 +6414,6 @@ def ffill(

pad = ffill

@overload
def bfill(
self: FrameOrSeries,
axis: None | Axis = ...,
inplace: Literal[False] = ...,
limit: None | int = ...,
downcast=...,
) -> FrameOrSeries:
...

@overload
def bfill(
self: FrameOrSeries,
axis: None | Axis,
inplace: Literal[True],
limit: None | int = ...,
downcast=...,
) -> None:
...

@overload
def bfill(
self: FrameOrSeries,
*,
inplace: Literal[True],
limit: None | int = ...,
downcast=...,
) -> None:
...

@overload
def bfill(
self: FrameOrSeries,
axis: None | Axis = ...,
inplace: bool_t = ...,
limit: None | int = ...,
downcast=...,
) -> FrameOrSeries | None:
...

@final
@doc(klass=_shared_doc_kwargs["klass"])
def bfill(
self: FrameOrSeries,
Expand Down
20 changes: 20 additions & 0 deletions pandas/core/series.py
Original file line number Diff line number Diff line change
Expand Up @@ -5292,6 +5292,26 @@ def to_period(self, freq=None, copy=True) -> Series:
self, method="to_period"
)

@deprecate_nonkeyword_arguments(version=None, allowed_args=["self"])
def ffill(
self: Series,
axis: None | Axis = None,
inplace: bool = False,
limit: None | int = None,
downcast=None,
) -> Series | None:
return super().ffill(axis, inplace, limit, downcast)

@deprecate_nonkeyword_arguments(version=None, allowed_args=["self"])
def bfill(
self: Series,
axis: None | Axis = None,
inplace: bool = False,
limit: None | int = None,
downcast=None,
) -> Series | None:
return super().bfill(axis, inplace, limit, downcast)

@deprecate_nonkeyword_arguments(
version=None, allowed_args=["self", "lower", "upper"]
)
Expand Down
24 changes: 24 additions & 0 deletions pandas/tests/frame/methods/test_fillna.py
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,18 @@ def test_ffill(self, datetime_frame):
datetime_frame.ffill(), datetime_frame.fillna(method="ffill")
)

def test_ffill_pos_args_deprecation(self):
# https://github.com/pandas-dev/pandas/issues/41485
df = DataFrame({"a": [1, 2, 3]})
msg = (
r"In a future version of pandas all arguments of DataFrame.ffill "
r"will be keyword-only"
)
with tm.assert_produces_warning(FutureWarning, match=msg):
result = df.ffill(0)
expected = DataFrame({"a": [1, 2, 3]})
tm.assert_frame_equal(result, expected)

def test_bfill(self, datetime_frame):
datetime_frame["A"][:5] = np.nan
datetime_frame["A"][-5:] = np.nan
Expand All @@ -334,6 +346,18 @@ def test_bfill(self, datetime_frame):
datetime_frame.bfill(), datetime_frame.fillna(method="bfill")
)

def test_bfill_pos_args_deprecation(self):
# https://github.com/pandas-dev/pandas/issues/41485
df = DataFrame({"a": [1, 2, 3]})
msg = (
r"In a future version of pandas all arguments of DataFrame.bfill "
r"will be keyword-only"
)
with tm.assert_produces_warning(FutureWarning, match=msg):
result = df.bfill(0)
expected = DataFrame({"a": [1, 2, 3]})
tm.assert_frame_equal(result, expected)

def test_frame_pad_backfill_limit(self):
index = np.arange(10)
df = DataFrame(np.random.randn(10, 4), index=index)
Expand Down
24 changes: 24 additions & 0 deletions pandas/tests/series/methods/test_fillna.py
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,18 @@ def test_ffill(self):
ts[2] = np.NaN
tm.assert_series_equal(ts.ffill(), ts.fillna(method="ffill"))

def test_ffill_pos_args_deprecation(self):
# https://github.com/pandas-dev/pandas/issues/41485
ser = Series([1, 2, 3])
msg = (
r"In a future version of pandas all arguments of Series.ffill "
r"will be keyword-only"
)
with tm.assert_produces_warning(FutureWarning, match=msg):
result = ser.ffill(0)
expected = Series([1, 2, 3])
tm.assert_series_equal(result, expected)

def test_ffill_mixed_dtypes_without_missing_data(self):
# GH#14956
series = Series([datetime(2015, 1, 1, tzinfo=pytz.utc), 1])
Expand All @@ -788,6 +800,18 @@ def test_bfill(self):
ts[2] = np.NaN
tm.assert_series_equal(ts.bfill(), ts.fillna(method="bfill"))

def test_bfill_pos_args_deprecation(self):
# https://github.com/pandas-dev/pandas/issues/41485
ser = Series([1, 2, 3])
msg = (
r"In a future version of pandas all arguments of Series.bfill "
r"will be keyword-only"
)
with tm.assert_produces_warning(FutureWarning, match=msg):
result = ser.bfill(0)
expected = Series([1, 2, 3])
tm.assert_series_equal(result, expected)

def test_pad_nan(self):
x = Series(
[np.nan, 1.0, np.nan, 3.0, np.nan], ["z", "a", "b", "c", "d"], dtype=float
Expand Down