Skip to content

Commit 74e8c00

Browse files
authored
DEPR: method, limit, fill_axis keywords in align (pandas-dev#51968)
1 parent 3fe439b commit 74e8c00

File tree

6 files changed

+105
-26
lines changed

6 files changed

+105
-26
lines changed

doc/source/whatsnew/v2.1.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ Deprecations
101101
- Deprecated ``axis=1`` in :meth:`DataFrame.groupby` and in :class:`Grouper` constructor, do ``frame.T.groupby(...)`` instead (:issue:`51203`)
102102
- Deprecated passing a :class:`DataFrame` to :meth:`DataFrame.from_records`, use :meth:`DataFrame.set_index` or :meth:`DataFrame.drop` instead (:issue:`51353`)
103103
- Deprecated accepting slices in :meth:`DataFrame.take`, call ``obj[slicer]`` or pass a sequence of integers instead (:issue:`51539`)
104+
- Deprecated 'method', 'limit', and 'fill_axis' keywords in :meth:`DataFrame.align` and :meth:`Series.align`, explicitly call ``fillna`` on the alignment results instead (:issue:`51856`)
104105
-
105106

106107
.. ---------------------------------------------------------------------------

pandas/core/frame.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -5014,9 +5014,9 @@ def align(
50145014
level: Level = None,
50155015
copy: bool | None = None,
50165016
fill_value=None,
5017-
method: FillnaOptions | None = None,
5018-
limit: int | None = None,
5019-
fill_axis: Axis = 0,
5017+
method: FillnaOptions | None | lib.NoDefault = lib.no_default,
5018+
limit: int | None | lib.NoDefault = lib.no_default,
5019+
fill_axis: Axis | lib.NoDefault = lib.no_default,
50205020
broadcast_axis: Axis | None = None,
50215021
) -> tuple[Self, NDFrameT]:
50225022
return super().align(

pandas/core/generic.py

+31-4
Original file line numberDiff line numberDiff line change
@@ -9318,9 +9318,9 @@ def align(
93189318
level: Level = None,
93199319
copy: bool_t | None = None,
93209320
fill_value: Hashable = None,
9321-
method: FillnaOptions | None = None,
9322-
limit: int | None = None,
9323-
fill_axis: Axis = 0,
9321+
method: FillnaOptions | None | lib.NoDefault = lib.no_default,
9322+
limit: int | None | lib.NoDefault = lib.no_default,
9323+
fill_axis: Axis | lib.NoDefault = lib.no_default,
93249324
broadcast_axis: Axis | None = None,
93259325
) -> tuple[Self, NDFrameT]:
93269326
"""
@@ -9349,15 +9349,23 @@ def align(
93499349
- pad / ffill: propagate last valid observation forward to next valid.
93509350
- backfill / bfill: use NEXT valid observation to fill gap.
93519351
9352+
.. deprecated:: 2.1
9353+
93529354
limit : int, default None
93539355
If method is specified, this is the maximum number of consecutive
93549356
NaN values to forward/backward fill. In other words, if there is
93559357
a gap with more than this number of consecutive NaNs, it will only
93569358
be partially filled. If method is not specified, this is the
93579359
maximum number of entries along the entire axis where NaNs will be
93589360
filled. Must be greater than 0 if not None.
9361+
9362+
.. deprecated:: 2.1
9363+
93599364
fill_axis : {axes_single_arg}, default 0
93609365
Filling axis, method and limit.
9366+
9367+
.. deprecated:: 2.1
9368+
93619369
broadcast_axis : {axes_single_arg}, default None
93629370
Broadcast values along this axis, if aligning two objects of
93639371
different dimensions.
@@ -9432,7 +9440,26 @@ def align(
94329440
3 60.0 70.0 80.0 90.0 NaN
94339441
4 600.0 700.0 800.0 900.0 NaN
94349442
"""
9435-
9443+
if (
9444+
method is not lib.no_default
9445+
or limit is not lib.no_default
9446+
or fill_axis is not lib.no_default
9447+
):
9448+
# GH#51856
9449+
warnings.warn(
9450+
"The 'method', 'limit', and 'fill_axis' keywords in "
9451+
f"{type(self).__name__}.align are deprecated and will be removed "
9452+
"in a future version. Call fillna directly on the returned objects "
9453+
"instead.",
9454+
FutureWarning,
9455+
stacklevel=find_stack_level(),
9456+
)
9457+
if fill_axis is lib.no_default:
9458+
fill_axis = 0
9459+
if method is lib.no_default:
9460+
method = None
9461+
if limit is lib.no_default:
9462+
limit = None
94369463
method = clean_fill_method(method)
94379464

94389465
if broadcast_axis == 1 and self.ndim != other.ndim:

pandas/core/series.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -4599,9 +4599,9 @@ def align(
45994599
level: Level = None,
46004600
copy: bool | None = None,
46014601
fill_value: Hashable = None,
4602-
method: FillnaOptions | None = None,
4603-
limit: int | None = None,
4604-
fill_axis: Axis = 0,
4602+
method: FillnaOptions | None | lib.NoDefault = lib.no_default,
4603+
limit: int | None | lib.NoDefault = lib.no_default,
4604+
fill_axis: Axis | lib.NoDefault = lib.no_default,
46054605
broadcast_axis: Axis | None = None,
46064606
) -> tuple[Self, NDFrameT]:
46074607
return super().align(

pandas/tests/frame/methods/test_align.py

+55-14
Original file line numberDiff line numberDiff line change
@@ -83,17 +83,32 @@ def test_align_float(self, float_frame, using_copy_on_write):
8383
af, bf = float_frame.align(other, join="inner", axis=1)
8484
tm.assert_index_equal(bf.columns, other.columns)
8585

86-
af, bf = float_frame.align(other, join="inner", axis=1, method="pad")
86+
msg = (
87+
"The 'method', 'limit', and 'fill_axis' keywords in DataFrame.align "
88+
"are deprecated"
89+
)
90+
with tm.assert_produces_warning(FutureWarning, match=msg):
91+
af, bf = float_frame.align(other, join="inner", axis=1, method="pad")
8792
tm.assert_index_equal(bf.columns, other.columns)
8893

89-
af, bf = float_frame.align(
90-
other.iloc[:, 0], join="inner", axis=1, method=None, fill_value=None
94+
msg = (
95+
"The 'method', 'limit', and 'fill_axis' keywords in DataFrame.align "
96+
"are deprecated"
9197
)
98+
with tm.assert_produces_warning(FutureWarning, match=msg):
99+
af, bf = float_frame.align(
100+
other.iloc[:, 0], join="inner", axis=1, method=None, fill_value=None
101+
)
92102
tm.assert_index_equal(bf.index, Index([]))
93103

94-
af, bf = float_frame.align(
95-
other.iloc[:, 0], join="inner", axis=1, method=None, fill_value=0
104+
msg = (
105+
"The 'method', 'limit', and 'fill_axis' keywords in DataFrame.align "
106+
"are deprecated"
96107
)
108+
with tm.assert_produces_warning(FutureWarning, match=msg):
109+
af, bf = float_frame.align(
110+
other.iloc[:, 0], join="inner", axis=1, method=None, fill_value=0
111+
)
97112
tm.assert_index_equal(bf.index, Index([]))
98113

99114
# Try to align DataFrame to Series along bad axis
@@ -134,30 +149,50 @@ def test_align_int(self, int_frame):
134149
# test other non-float types
135150
other = DataFrame(index=range(5), columns=["A", "B", "C"])
136151

137-
af, bf = int_frame.align(other, join="inner", axis=1, method="pad")
152+
msg = (
153+
"The 'method', 'limit', and 'fill_axis' keywords in DataFrame.align "
154+
"are deprecated"
155+
)
156+
with tm.assert_produces_warning(FutureWarning, match=msg):
157+
af, bf = int_frame.align(other, join="inner", axis=1, method="pad")
138158
tm.assert_index_equal(bf.columns, other.columns)
139159

140160
def test_align_mixed_type(self, float_string_frame):
141-
af, bf = float_string_frame.align(
142-
float_string_frame, join="inner", axis=1, method="pad"
161+
msg = (
162+
"The 'method', 'limit', and 'fill_axis' keywords in DataFrame.align "
163+
"are deprecated"
143164
)
165+
with tm.assert_produces_warning(FutureWarning, match=msg):
166+
af, bf = float_string_frame.align(
167+
float_string_frame, join="inner", axis=1, method="pad"
168+
)
144169
tm.assert_index_equal(bf.columns, float_string_frame.columns)
145170

146171
def test_align_mixed_float(self, mixed_float_frame):
147172
# mixed floats/ints
148173
other = DataFrame(index=range(5), columns=["A", "B", "C"])
149174

150-
af, bf = mixed_float_frame.align(
151-
other.iloc[:, 0], join="inner", axis=1, method=None, fill_value=0
175+
msg = (
176+
"The 'method', 'limit', and 'fill_axis' keywords in DataFrame.align "
177+
"are deprecated"
152178
)
179+
with tm.assert_produces_warning(FutureWarning, match=msg):
180+
af, bf = mixed_float_frame.align(
181+
other.iloc[:, 0], join="inner", axis=1, method=None, fill_value=0
182+
)
153183
tm.assert_index_equal(bf.index, Index([]))
154184

155185
def test_align_mixed_int(self, mixed_int_frame):
156186
other = DataFrame(index=range(5), columns=["A", "B", "C"])
157187

158-
af, bf = mixed_int_frame.align(
159-
other.iloc[:, 0], join="inner", axis=1, method=None, fill_value=0
188+
msg = (
189+
"The 'method', 'limit', and 'fill_axis' keywords in DataFrame.align "
190+
"are deprecated"
160191
)
192+
with tm.assert_produces_warning(FutureWarning, match=msg):
193+
af, bf = mixed_int_frame.align(
194+
other.iloc[:, 0], join="inner", axis=1, method=None, fill_value=0
195+
)
161196
tm.assert_index_equal(bf.index, Index([]))
162197

163198
@pytest.mark.parametrize(
@@ -348,10 +383,16 @@ def test_missing_axis_specification_exception(self):
348383
df.align(series)
349384

350385
def _check_align(self, a, b, axis, fill_axis, how, method, limit=None):
351-
aa, ab = a.align(
352-
b, axis=axis, join=how, method=method, limit=limit, fill_axis=fill_axis
386+
msg = (
387+
"The 'method', 'limit', and 'fill_axis' keywords in DataFrame.align "
388+
"are deprecated"
353389
)
354390

391+
with tm.assert_produces_warning(FutureWarning, match=msg):
392+
aa, ab = a.align(
393+
b, axis=axis, join=how, method=method, limit=limit, fill_axis=fill_axis
394+
)
395+
355396
join_index, join_columns = None, None
356397

357398
ea, eb = a, b

pandas/tests/series/methods/test_align.py

+12-2
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,12 @@ def test_align_fill_method(
6969
a = datetime_series[slice(*first_slice)]
7070
b = datetime_series[slice(*second_slice)]
7171

72-
aa, ab = a.align(b, join=join_type, method=method, limit=limit)
72+
msg = (
73+
"The 'method', 'limit', and 'fill_axis' keywords in Series.align "
74+
"are deprecated"
75+
)
76+
with tm.assert_produces_warning(FutureWarning, match=msg):
77+
aa, ab = a.align(b, join=join_type, method=method, limit=limit)
7378

7479
join_index = a.index.join(b.index, how=join_type)
7580
ea = a.reindex(join_index)
@@ -173,7 +178,12 @@ def test_align_with_dataframe_method(method):
173178
ser = Series(range(3), index=range(3))
174179
df = pd.DataFrame(0.0, index=range(3), columns=range(3))
175180

176-
result_ser, result_df = ser.align(df, method=method)
181+
msg = (
182+
"The 'method', 'limit', and 'fill_axis' keywords in Series.align "
183+
"are deprecated"
184+
)
185+
with tm.assert_produces_warning(FutureWarning, match=msg):
186+
result_ser, result_df = ser.align(df, method=method)
177187
tm.assert_series_equal(result_ser, ser)
178188
tm.assert_frame_equal(result_df, df)
179189

0 commit comments

Comments
 (0)