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

DEPR: downcast keyword #53671

Merged
merged 9 commits into from
Jun 29, 2023
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/source/whatsnew/v2.1.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ Deprecations
- Deprecated making the functions in a list of functions given to :meth:`DataFrame.agg` attempt to operate on each element in the :class:`DataFrame` and only operate on the columns of the :class:`DataFrame` if the elementwise operations failed. To keep the current behavior, use :meth:`DataFrame.transform` instead. (:issue:`53325`)
- Deprecated passing a :class:`DataFrame` to :meth:`DataFrame.from_records`, use :meth:`DataFrame.set_index` or :meth:`DataFrame.drop` instead (:issue:`51353`)
- Deprecated silently dropping unrecognized timezones when parsing strings to datetimes (:issue:`18702`)
- Deprecated the "downcast" keyword in :meth:`Series.interpolate`, :meth:`DataFrame.interpolate`, :meth:`Series.fillna`, :meth:`DataFrame.fillna`, :meth:`Series.ffill`, :meth:`DataFrame.ffill`, :meth:`Series.bfill`, :meth:`DataFrame.bfill` (:issue:`40988`)
- Deprecated the ``axis`` keyword in :meth:`DataFrame.ewm`, :meth:`Series.ewm`, :meth:`DataFrame.rolling`, :meth:`Series.rolling`, :meth:`DataFrame.expanding`, :meth:`Series.expanding` (:issue:`51778`)
- Deprecated the ``axis`` keyword in :meth:`DataFrame.resample`, :meth:`Series.resample` (:issue:`51778`)
- Deprecated the behavior of :func:`concat` with both ``len(keys) != len(objs)``, in a future version this will raise instead of truncating to the shorter of the two sequences (:issue:`43485`)
Expand Down Expand Up @@ -292,7 +293,6 @@ Deprecations
- Deprecated :meth:`Series.first` and :meth:`DataFrame.first` (please create a mask and filter using ``.loc`` instead) (:issue:`45908`)
- Deprecated :meth:`Series.interpolate` and :meth:`DataFrame.interpolate` for object-dtype (:issue:`53631`)
- Deprecated :meth:`Series.last` and :meth:`DataFrame.last` (please create a mask and filter using ``.loc`` instead) (:issue:`53692`)
- Deprecated allowing ``downcast`` keyword other than ``None``, ``False``, "infer", or a dict with these as values in :meth:`Series.fillna`, :meth:`DataFrame.fillna` (:issue:`40988`)
- Deprecated allowing arbitrary ``fill_value`` in :class:`SparseDtype`, in a future version the ``fill_value`` will need to be compatible with the ``dtype.subtype``, either a scalar that can be held by that subtype or ``NaN`` for integer or bool subtypes (:issue:`23124`)
- Deprecated behavior of :func:`assert_series_equal` and :func:`assert_frame_equal` considering NA-like values (e.g. ``NaN`` vs ``None`` as equivalent) (:issue:`52081`)
- Deprecated bytes input to :func:`read_excel`. To read a file path, use a string or path-like object. (:issue:`53767`)
Expand Down
136 changes: 83 additions & 53 deletions pandas/core/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -6870,25 +6870,21 @@ def convert_dtypes(
# ----------------------------------------------------------------------
# Filling NA's

def _deprecate_downcast(self, downcast) -> None:
if isinstance(downcast, dict):
# GH#40988
for dc in downcast.values():
if dc is not None and dc is not False and dc != "infer":
warnings.warn(
"downcast entries other than None, False, and 'infer' "
"are deprecated and will raise in a future version",
FutureWarning,
stacklevel=find_stack_level(),
)
elif downcast is not None and downcast is not False and downcast != "infer":
# GH#40988
def _deprecate_downcast(self, downcast, method_name: str):
# GH#40988
if downcast is not lib.no_default:
warnings.warn(
"downcast other than None, False, and 'infer' are deprecated "
"and will raise in a future version",
f"The 'downcast' keyword in {method_name} is deprecated and "
"will be removed in a future version. Use "
"res.infer_objects(copy=False) to infer non-object dtype, or "
"pd.to_numeric with the 'downcast' keyword to downcast numeric "
"results.",
FutureWarning,
stacklevel=find_stack_level(),
)
else:
downcast = None
return downcast

@final
def _pad_or_backfill(
Expand Down Expand Up @@ -6977,7 +6973,7 @@ def fillna(
axis: Axis | None = None,
inplace: bool_t = False,
limit: int | None = None,
downcast: dict | None = None,
downcast: dict | None | lib.NoDefault = lib.no_default,
) -> Self | None:
"""
Fill NA/NaN values using the specified method.
Expand Down Expand Up @@ -7096,7 +7092,8 @@ def fillna(
stacklevel=find_stack_level(),
)

self._deprecate_downcast(downcast)
was_no_default = downcast is lib.no_default
downcast = self._deprecate_downcast(downcast, "fillna")

# set the default here, so functions examining the signaure
# can detect if something was set (e.g. in groupby) (GH9221)
Expand All @@ -7113,7 +7110,11 @@ def fillna(
axis=axis,
limit=limit,
inplace=inplace,
downcast=downcast,
# error: Argument "downcast" to "_fillna_with_method" of "NDFrame"
# has incompatible type "Union[Dict[Any, Any], None,
# Literal[_NoDefault.no_default]]"; expected
# "Optional[Dict[Any, Any]]"
downcast=downcast, # type: ignore[arg-type]
)
else:
if self.ndim == 1:
Expand Down Expand Up @@ -7157,13 +7158,20 @@ def fillna(
if k not in result:
continue

# error: Item "None" of "Optional[Dict[Any, Any]]" has no
# attribute "get"
downcast_k = (
downcast
if not is_dict
else downcast.get(k) # type: ignore[union-attr]
)
if was_no_default:
downcast_k = lib.no_default
else:
downcast_k = (
# error: Incompatible types in assignment (expression
# has type "Union[Dict[Any, Any], None,
# Literal[_NoDefault.no_default], Any]", variable has
# type "_NoDefault")
downcast # type: ignore[assignment]
if not is_dict
# error: Item "None" of "Optional[Dict[Any, Any]]" has
# no attribute "get"
else downcast.get(k) # type: ignore[union-attr]
)

res_k = result[k].fillna(v, limit=limit, downcast=downcast_k)

Expand Down Expand Up @@ -7236,7 +7244,7 @@ def ffill(
axis: None | Axis = ...,
inplace: Literal[False] = ...,
limit: None | int = ...,
downcast: dict | None = ...,
downcast: dict | None | lib.NoDefault = ...,
) -> Self:
...

Expand All @@ -7247,7 +7255,7 @@ def ffill(
axis: None | Axis = ...,
inplace: Literal[True],
limit: None | int = ...,
downcast: dict | None = ...,
downcast: dict | None | lib.NoDefault = ...,
) -> None:
...

Expand All @@ -7258,7 +7266,7 @@ def ffill(
axis: None | Axis = ...,
inplace: bool_t = ...,
limit: None | int = ...,
downcast: dict | None = ...,
downcast: dict | None | lib.NoDefault = ...,
) -> Self | None:
...

Expand All @@ -7270,7 +7278,7 @@ def ffill(
axis: None | Axis = None,
inplace: bool_t = False,
limit: None | int = None,
downcast: dict | None = None,
downcast: dict | None | lib.NoDefault = lib.no_default,
) -> Self | None:
"""
Synonym for :meth:`DataFrame.fillna` with ``method='ffill'``.
Expand Down Expand Up @@ -7309,10 +7317,17 @@ def ffill(
3 3.0
dtype: float64
"""
self._deprecate_downcast(downcast)
downcast = self._deprecate_downcast(downcast, "ffill")

return self._pad_or_backfill(
"ffill", axis=axis, inplace=inplace, limit=limit, downcast=downcast
"ffill",
axis=axis,
inplace=inplace,
limit=limit,
# error: Argument "downcast" to "_fillna_with_method" of "NDFrame"
# has incompatible type "Union[Dict[Any, Any], None,
# Literal[_NoDefault.no_default]]"; expected "Optional[Dict[Any, Any]]"
downcast=downcast, # type: ignore[arg-type]
)

@final
Expand All @@ -7323,7 +7338,7 @@ def pad(
axis: None | Axis = None,
inplace: bool_t = False,
limit: None | int = None,
downcast: dict | None = None,
downcast: dict | None | lib.NoDefault = lib.no_default,
) -> Self | None:
"""
Synonym for :meth:`DataFrame.fillna` with ``method='ffill'``.
Expand Down Expand Up @@ -7352,7 +7367,7 @@ def bfill(
axis: None | Axis = ...,
inplace: Literal[False] = ...,
limit: None | int = ...,
downcast: dict | None = ...,
downcast: dict | None | lib.NoDefault = ...,
) -> Self:
...

Expand All @@ -7363,7 +7378,7 @@ def bfill(
axis: None | Axis = ...,
inplace: Literal[True],
limit: None | int = ...,
downcast: dict | None = ...,
downcast: dict | None | lib.NoDefault = ...,
) -> None:
...

Expand All @@ -7374,7 +7389,7 @@ def bfill(
axis: None | Axis = ...,
inplace: bool_t = ...,
limit: None | int = ...,
downcast: dict | None = ...,
downcast: dict | None | lib.NoDefault = ...,
) -> Self | None:
...

Expand All @@ -7386,7 +7401,7 @@ def bfill(
axis: None | Axis = None,
inplace: bool_t = False,
limit: None | int = None,
downcast: dict | None = None,
downcast: dict | None | lib.NoDefault = lib.no_default,
) -> Self | None:
"""
Synonym for :meth:`DataFrame.fillna` with ``method='bfill'``.
Expand All @@ -7407,12 +7422,6 @@ def bfill(
2 2.0
3 2.0
dtype: float64
>>> s.bfill(downcast='infer')
0 1
1 2
2 2
3 2
dtype: int64
>>> s.bfill(limit=1)
0 1.0
1 NaN
Expand All @@ -7435,16 +7444,23 @@ def bfill(
1 4.0 5.0
2 4.0 7.0
3 4.0 7.0
>>> df.bfill(downcast='infer', limit=1)
A B
0 1.0 5
1 NaN 5
2 4.0 7
3 4.0 7
"""
self._deprecate_downcast(downcast)
>>> df.bfill(limit=1)
A B
0 1.0 5.0
1 NaN 5.0
2 4.0 7.0
3 4.0 7.0
"""
downcast = self._deprecate_downcast(downcast, "bfill")
return self._pad_or_backfill(
"bfill", axis=axis, inplace=inplace, limit=limit, downcast=downcast
"bfill",
axis=axis,
inplace=inplace,
limit=limit,
# error: Argument "downcast" to "_fillna_with_method" of "NDFrame"
# has incompatible type "Union[Dict[Any, Any], None,
# Literal[_NoDefault.no_default]]"; expected "Optional[Dict[Any, Any]]"
downcast=downcast, # type: ignore[arg-type]
)

@final
Expand All @@ -7455,7 +7471,7 @@ def backfill(
axis: None | Axis = None,
inplace: bool_t = False,
limit: None | int = None,
downcast: dict | None = None,
downcast: dict | None | lib.NoDefault = lib.no_default,
) -> Self | None:
"""
Synonym for :meth:`DataFrame.fillna` with ``method='bfill'``.
Expand Down Expand Up @@ -7780,7 +7796,7 @@ def interpolate(
inplace: bool_t = False,
limit_direction: Literal["forward", "backward", "both"] | None = None,
limit_area: Literal["inside", "outside"] | None = None,
downcast: Literal["infer"] | None = None,
downcast: Literal["infer"] | None | lib.NoDefault = lib.no_default,
**kwargs,
) -> Self | None:
"""
Expand Down Expand Up @@ -7851,6 +7867,9 @@ def interpolate(

downcast : optional, 'infer' or None, defaults to None
Downcast dtypes if possible.

.. deprecated:: 2.1.0

``**kwargs`` : optional
Keyword arguments to pass on to the interpolating function.

Expand Down Expand Up @@ -7949,6 +7968,17 @@ def interpolate(
3 16.0
Name: d, dtype: float64
"""
if downcast is not lib.no_default:
# GH#40988
warnings.warn(
f"The 'downcast' keyword in {type(self).__name__}.interpolate "
"is deprecated and will be removed in a future version. "
"Call result.infer_objects(copy=False) on the result instead.",
FutureWarning,
stacklevel=find_stack_level(),
)
else:
downcast = None
if downcast is not None and downcast != "infer":
raise ValueError("downcast must be either None or 'infer'")

Expand Down
8 changes: 6 additions & 2 deletions pandas/core/groupby/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -868,7 +868,7 @@ def fillna(
axis: Axis | None | lib.NoDefault = lib.no_default,
inplace: bool = False,
limit: int | None = None,
downcast: dict | None = None,
downcast: dict | None | lib.NoDefault = lib.no_default,
) -> Series | None:
"""
Fill NA/NaN values using the specified method within groups.
Expand Down Expand Up @@ -912,6 +912,8 @@ def fillna(
or the string 'infer' which will try to downcast to an appropriate
equal type (e.g. float64 to int64 if possible).

.. deprecated:: 2.1.0

Returns
-------
Series
Expand Down Expand Up @@ -2390,7 +2392,7 @@ def fillna(
axis: Axis | None | lib.NoDefault = lib.no_default,
inplace: bool = False,
limit: int | None = None,
downcast=None,
downcast=lib.no_default,
) -> DataFrame | None:
"""
Fill NA/NaN values using the specified method within groups.
Expand Down Expand Up @@ -2434,6 +2436,8 @@ def fillna(
or the string 'infer' which will try to downcast to an appropriate
equal type (e.g. float64 to int64 if possible).

.. deprecated:: 2.1.0

Returns
-------
DataFrame
Expand Down
6 changes: 5 additions & 1 deletion pandas/core/resample.py
Original file line number Diff line number Diff line change
Expand Up @@ -844,7 +844,7 @@ def interpolate(
inplace: bool = False,
limit_direction: Literal["forward", "backward", "both"] = "forward",
limit_area=None,
downcast=None,
downcast=lib.no_default,
**kwargs,
):
"""
Expand Down Expand Up @@ -917,6 +917,9 @@ def interpolate(

downcast : optional, 'infer' or None, defaults to None
Downcast dtypes if possible.

.. deprecated::2.1.0

``**kwargs`` : optional
Keyword arguments to pass on to the interpolating function.

Expand Down Expand Up @@ -1000,6 +1003,7 @@ def interpolate(
Note that the series erroneously increases between two anchors
``07:00:00`` and ``07:00:02``.
"""
assert downcast is lib.no_default # just checking coverage
result = self._upsample("asfreq")
return result.interpolate(
method=method,
Expand Down
Loading