@@ -6803,6 +6803,61 @@ def convert_dtypes(
6803
6803
# ----------------------------------------------------------------------
6804
6804
# Filling NA's
6805
6805
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
+
6806
6861
@overload
6807
6862
def fillna (
6808
6863
self ,
@@ -6874,6 +6929,9 @@ def fillna(
6874
6929
* ffill: propagate last valid observation forward to next valid.
6875
6930
* backfill / bfill: use next valid observation to fill gap.
6876
6931
6932
+ .. deprecated:: 2.1.0
6933
+ Use ffill or bfill instead.
6934
+
6877
6935
axis : {axes_single_arg}
6878
6936
Axis along which to fill missing values. For `Series`
6879
6937
this parameter is unused and defaults to 0.
@@ -6927,15 +6985,6 @@ def fillna(
6927
6985
2 0.0 0.0 0.0 0.0
6928
6986
3 0.0 3.0 0.0 4.0
6929
6987
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
-
6939
6988
Replace all NaN elements in column 'A', 'B', 'C', and 'D', with 0, 1,
6940
6989
2, and 3 respectively.
6941
6990
@@ -6971,42 +7020,29 @@ def fillna(
6971
7020
"""
6972
7021
inplace = validate_bool_kwarg (inplace , "inplace" )
6973
7022
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 :
6987
7024
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." ,
6990
7028
FutureWarning ,
6991
7029
stacklevel = find_stack_level (),
6992
7030
)
6993
7031
7032
+ self ._deprecate_downcast (downcast )
7033
+
6994
7034
# set the default here, so functions examining the signaure
6995
7035
# can detect if something was set (e.g. in groupby) (GH9221)
6996
7036
if axis is None :
6997
7037
axis = 0
6998
7038
axis = self ._get_axis_number (axis )
6999
7039
7000
7040
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]
7010
7046
axis = axis ,
7011
7047
limit = limit ,
7012
7048
inplace = inplace ,
@@ -7111,7 +7147,10 @@ def fillna(
7111
7147
if axis == 1 :
7112
7148
result = self .T .fillna (value = value , limit = limit ).T
7113
7149
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]
7115
7154
else :
7116
7155
new_data = self ._mgr .fillna (
7117
7156
value = value , limit = limit , inplace = inplace , downcast = downcast
@@ -7180,6 +7219,25 @@ def ffill(
7180
7219
7181
7220
Examples
7182
7221
--------
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
+
7183
7241
>>> ser = pd.Series([1, np.NaN, 2, 3])
7184
7242
>>> ser.ffill()
7185
7243
0 1.0
@@ -7188,8 +7246,10 @@ def ffill(
7188
7246
3 3.0
7189
7247
dtype: float64
7190
7248
"""
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
7193
7253
)
7194
7254
7195
7255
@final
@@ -7319,8 +7379,9 @@ def bfill(
7319
7379
2 4.0 7
7320
7380
3 4.0 7
7321
7381
"""
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
7324
7385
)
7325
7386
7326
7387
@final
@@ -9840,8 +9901,8 @@ def _align_frame(
9840
9901
)
9841
9902
9842
9903
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 )
9845
9906
9846
9907
return left , right , join_index
9847
9908
@@ -9916,8 +9977,13 @@ def _align_series(
9916
9977
# fill
9917
9978
fill_na = notna (fill_value ) or (method is not None )
9918
9979
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 )
9921
9987
9922
9988
return left , right , join_index
9923
9989
@@ -11283,9 +11349,7 @@ def pct_change(
11283
11349
if fill_method is None :
11284
11350
data = self
11285
11351
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 )
11289
11353
11290
11354
shifted = data .shift (periods = periods , freq = freq , axis = axis , ** kwargs )
11291
11355
# Unsupported left operand type for / ("Self")
0 commit comments