@@ -6803,6 +6803,61 @@ def convert_dtypes(
68036803 # ----------------------------------------------------------------------
68046804 # Filling NA's
68056805
6806+ def _deprecate_downcast (self , downcast ) -> None :
6807+ if isinstance (downcast , dict ):
6808+ # GH#40988
6809+ for dc in downcast .values ():
6810+ if dc is not None and dc is not False and dc != "infer" :
6811+ warnings .warn (
6812+ "downcast entries other than None, False, and 'infer' "
6813+ "are deprecated and will raise in a future version" ,
6814+ FutureWarning ,
6815+ stacklevel = find_stack_level (),
6816+ )
6817+ elif downcast is not None and downcast is not False and downcast != "infer" :
6818+ # GH#40988
6819+ warnings .warn (
6820+ "downcast other than None, False, and 'infer' are deprecated "
6821+ "and will raise in a future version" ,
6822+ FutureWarning ,
6823+ stacklevel = find_stack_level (),
6824+ )
6825+
6826+ @final
6827+ def _fillna_with_method (
6828+ self ,
6829+ method : Literal ["ffill" , "bfill" , "pad" , "backfill" ],
6830+ * ,
6831+ axis : None | Axis = None ,
6832+ inplace : bool_t = False ,
6833+ limit : None | int = None ,
6834+ downcast : dict | None = None ,
6835+ ):
6836+ if axis is None :
6837+ axis = 0
6838+ axis = self ._get_axis_number (axis )
6839+ method = clean_fill_method (method )
6840+
6841+ if not self ._mgr .is_single_block and axis == 1 :
6842+ if inplace :
6843+ raise NotImplementedError ()
6844+ result = self .T ._fillna_with_method (method = method , limit = limit ).T
6845+
6846+ return result
6847+
6848+ new_mgr = self ._mgr .interpolate (
6849+ method = method ,
6850+ axis = axis ,
6851+ limit = limit ,
6852+ inplace = inplace ,
6853+ downcast = downcast ,
6854+ )
6855+ result = self ._constructor (new_mgr )
6856+ if inplace :
6857+ return self ._update_inplace (result )
6858+ else :
6859+ return result .__finalize__ (self , method = "fillna" )
6860+
68066861 @overload
68076862 def fillna (
68086863 self ,
@@ -6874,6 +6929,9 @@ def fillna(
68746929 * ffill: propagate last valid observation forward to next valid.
68756930 * backfill / bfill: use next valid observation to fill gap.
68766931
6932+ .. deprecated:: 2.1.0
6933+ Use ffill or bfill instead.
6934+
68776935 axis : {axes_single_arg}
68786936 Axis along which to fill missing values. For `Series`
68796937 this parameter is unused and defaults to 0.
@@ -6927,15 +6985,6 @@ def fillna(
69276985 2 0.0 0.0 0.0 0.0
69286986 3 0.0 3.0 0.0 4.0
69296987
6930- We can also propagate non-null values forward or backward.
6931-
6932- >>> df.fillna(method="ffill")
6933- A B C D
6934- 0 NaN 2.0 NaN 0.0
6935- 1 3.0 4.0 NaN 1.0
6936- 2 3.0 4.0 NaN 1.0
6937- 3 3.0 3.0 NaN 4.0
6938-
69396988 Replace all NaN elements in column 'A', 'B', 'C', and 'D', with 0, 1,
69406989 2, and 3 respectively.
69416990
@@ -6971,42 +7020,29 @@ def fillna(
69717020 """
69727021 inplace = validate_bool_kwarg (inplace , "inplace" )
69737022 value , method = validate_fillna_kwargs (value , method )
6974-
6975- if isinstance (downcast , dict ):
6976- # GH#40988
6977- for dc in downcast .values ():
6978- if dc is not None and dc is not False and dc != "infer" :
6979- warnings .warn (
6980- "downcast entries other than None, False, and 'infer' "
6981- "are deprecated and will raise in a future version" ,
6982- FutureWarning ,
6983- stacklevel = find_stack_level (),
6984- )
6985- elif downcast is not None and downcast is not False and downcast != "infer" :
6986- # GH#40988
7023+ if method is not None :
69877024 warnings .warn (
6988- "downcast other than None, False, and 'infer' are deprecated "
6989- "and will raise in a future version" ,
7025+ f"{ type (self ).__name__ } .fillna with 'method' is deprecated and "
7026+ "will raise in a future version. Use obj.ffill() or obj.bfill() "
7027+ "instead." ,
69907028 FutureWarning ,
69917029 stacklevel = find_stack_level (),
69927030 )
69937031
7032+ self ._deprecate_downcast (downcast )
7033+
69947034 # set the default here, so functions examining the signaure
69957035 # can detect if something was set (e.g. in groupby) (GH9221)
69967036 if axis is None :
69977037 axis = 0
69987038 axis = self ._get_axis_number (axis )
69997039
70007040 if value is None :
7001- if not self ._mgr .is_single_block and axis == 1 :
7002- if inplace :
7003- raise NotImplementedError ()
7004- result = self .T .fillna (method = method , limit = limit ).T
7005-
7006- return result
7007-
7008- new_data = self ._mgr .interpolate (
7009- method = method ,
7041+ return self ._fillna_with_method (
7042+ # error: Argument 1 to "_fillna_with_method" of "NDFrame" has
7043+ # incompatible type "Optional[Literal['backfill', 'bfill', 'ffill',
7044+ # 'pad']]"; expected "Literal['ffill', 'bfill', 'pad', 'backfill']"
7045+ method , # type: ignore[arg-type]
70107046 axis = axis ,
70117047 limit = limit ,
70127048 inplace = inplace ,
@@ -7111,7 +7147,10 @@ def fillna(
71117147 if axis == 1 :
71127148 result = self .T .fillna (value = value , limit = limit ).T
71137149
7114- new_data = result
7150+ # error: Incompatible types in assignment (expression
7151+ # has type "Self", variable has type "Union[ArrayManager,
7152+ # SingleArrayManager, BlockManager, SingleBlockManager]")
7153+ new_data = result # type: ignore[assignment]
71157154 else :
71167155 new_data = self ._mgr .fillna (
71177156 value = value , limit = limit , inplace = inplace , downcast = downcast
@@ -7180,6 +7219,25 @@ def ffill(
71807219
71817220 Examples
71827221 --------
7222+ >>> df = pd.DataFrame([[np.nan, 2, np.nan, 0],
7223+ ... [3, 4, np.nan, 1],
7224+ ... [np.nan, np.nan, np.nan, np.nan],
7225+ ... [np.nan, 3, np.nan, 4]],
7226+ ... columns=list("ABCD"))
7227+ >>> df
7228+ A B C D
7229+ 0 NaN 2.0 NaN 0.0
7230+ 1 3.0 4.0 NaN 1.0
7231+ 2 NaN NaN NaN NaN
7232+ 3 NaN 3.0 NaN 4.0
7233+
7234+ >>> df.ffill()
7235+ A B C D
7236+ 0 NaN 2.0 NaN 0.0
7237+ 1 3.0 4.0 NaN 1.0
7238+ 2 3.0 4.0 NaN 1.0
7239+ 3 3.0 3.0 NaN 4.0
7240+
71837241 >>> ser = pd.Series([1, np.NaN, 2, 3])
71847242 >>> ser.ffill()
71857243 0 1.0
@@ -7188,8 +7246,10 @@ def ffill(
71887246 3 3.0
71897247 dtype: float64
71907248 """
7191- return self .fillna (
7192- method = "ffill" , axis = axis , inplace = inplace , limit = limit , downcast = downcast
7249+ self ._deprecate_downcast (downcast )
7250+
7251+ return self ._fillna_with_method (
7252+ "ffill" , axis = axis , inplace = inplace , limit = limit , downcast = downcast
71937253 )
71947254
71957255 @final
@@ -7319,8 +7379,9 @@ def bfill(
73197379 2 4.0 7
73207380 3 4.0 7
73217381 """
7322- return self .fillna (
7323- method = "bfill" , axis = axis , inplace = inplace , limit = limit , downcast = downcast
7382+ self ._deprecate_downcast (downcast )
7383+ return self ._fillna_with_method (
7384+ "bfill" , axis = axis , inplace = inplace , limit = limit , downcast = downcast
73247385 )
73257386
73267387 @final
@@ -9840,8 +9901,8 @@ def _align_frame(
98409901 )
98419902
98429903 if method is not None :
9843- left = left .fillna ( method = method , axis = fill_axis , limit = limit )
9844- right = right .fillna ( method = method , axis = fill_axis , limit = limit )
9904+ left = left ._fillna_with_method ( method , axis = fill_axis , limit = limit )
9905+ right = right ._fillna_with_method ( method , axis = fill_axis , limit = limit )
98459906
98469907 return left , right , join_index
98479908
@@ -9916,8 +9977,13 @@ def _align_series(
99169977 # fill
99179978 fill_na = notna (fill_value ) or (method is not None )
99189979 if fill_na :
9919- left = left .fillna (fill_value , method = method , limit = limit , axis = fill_axis )
9920- right = right .fillna (fill_value , method = method , limit = limit )
9980+ fill_value , method = validate_fillna_kwargs (fill_value , method )
9981+ if method is not None :
9982+ left = left ._fillna_with_method (method , limit = limit , axis = fill_axis )
9983+ right = right ._fillna_with_method (method , limit = limit )
9984+ else :
9985+ left = left .fillna (fill_value , limit = limit , axis = fill_axis )
9986+ right = right .fillna (fill_value , limit = limit )
99219987
99229988 return left , right , join_index
99239989
@@ -11283,9 +11349,7 @@ def pct_change(
1128311349 if fill_method is None :
1128411350 data = self
1128511351 else :
11286- _data = self .fillna (method = fill_method , axis = axis , limit = limit )
11287- assert _data is not None # needed for mypy
11288- data = _data
11352+ data = self ._fillna_with_method (fill_method , axis = axis , limit = limit )
1128911353
1129011354 shifted = data .shift (periods = periods , freq = freq , axis = axis , ** kwargs )
1129111355 # Unsupported left operand type for / ("Self")
0 commit comments