Skip to content

Commit d3ae4e9

Browse files
committed
Merge remote-tracking branch 'upstream/main' into ref/is_range_indexer/step
2 parents 997416f + d2bf501 commit d3ae4e9

File tree

14 files changed

+168
-215
lines changed

14 files changed

+168
-215
lines changed

doc/source/whatsnew/v0.10.0.rst

+30-6
Original file line numberDiff line numberDiff line change
@@ -242,18 +242,42 @@ labeled the aggregated group with the end of the interval: the next day).
242242
- Calling ``fillna`` on Series or DataFrame with no arguments is no longer
243243
valid code. You must either specify a fill value or an interpolation method:
244244

245-
.. ipython:: python
246-
:okwarning:
245+
.. code-block:: ipython
247246
248-
s = pd.Series([np.nan, 1.0, 2.0, np.nan, 4])
249-
s
250-
s.fillna(0)
251-
s.fillna(method="pad")
247+
In [6]: s = pd.Series([np.nan, 1.0, 2.0, np.nan, 4])
248+
249+
In [7]: s
250+
Out[7]:
251+
0 NaN
252+
1 1.0
253+
2 2.0
254+
3 NaN
255+
4 4.0
256+
dtype: float64
257+
258+
In [8]: s.fillna(0)
259+
Out[8]:
260+
0 0.0
261+
1 1.0
262+
2 2.0
263+
3 0.0
264+
4 4.0
265+
dtype: float64
266+
267+
In [9]: s.fillna(method="pad")
268+
Out[9]:
269+
0 NaN
270+
1 1.0
271+
2 2.0
272+
3 2.0
273+
4 4.0
274+
dtype: float64
252275
253276
Convenience methods ``ffill`` and ``bfill`` have been added:
254277

255278
.. ipython:: python
256279
280+
s = pd.Series([np.nan, 1.0, 2.0, np.nan, 4])
257281
s.ffill()
258282
259283

doc/source/whatsnew/v3.0.0.rst

+2
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ Removal of prior version deprecations/changes
241241
- Removed argument ``limit`` from :meth:`DataFrame.pct_change`, :meth:`Series.pct_change`, :meth:`.DataFrameGroupBy.pct_change`, and :meth:`.SeriesGroupBy.pct_change`; the argument ``method`` must be set to ``None`` and will be removed in a future version of pandas (:issue:`53520`)
242242
- Removed deprecated argument ``obj`` in :meth:`.DataFrameGroupBy.get_group` and :meth:`.SeriesGroupBy.get_group` (:issue:`53545`)
243243
- Removed deprecated behavior of :meth:`Series.agg` using :meth:`Series.apply` (:issue:`53325`)
244+
- Removed deprecated keyword ``method`` on :meth:`Series.fillna`, :meth:`DataFrame.fillna` (:issue:`57760`)
244245
- Removed option ``mode.use_inf_as_na``, convert inf entries to ``NaN`` before instead (:issue:`51684`)
245246
- Removed support for :class:`DataFrame` in :meth:`DataFrame.from_records`(:issue:`51697`)
246247
- Removed support for ``errors="ignore"`` in :func:`to_datetime`, :func:`to_timedelta` and :func:`to_numeric` (:issue:`55734`)
@@ -274,6 +275,7 @@ Performance improvements
274275
- Performance improvement in :meth:`MultiIndex.equals` for equal length indexes (:issue:`56990`)
275276
- Performance improvement in :meth:`RangeIndex.__getitem__` with a boolean mask or integers returning a :class:`RangeIndex` instead of a :class:`Index` when possible. (:issue:`57588`)
276277
- Performance improvement in :meth:`RangeIndex.append` when appending the same index (:issue:`57252`)
278+
- Performance improvement in :meth:`RangeIndex.argmin` and :meth:`RangeIndex.argmax` (:issue:`57823`)
277279
- Performance improvement in :meth:`RangeIndex.round` returning a :class:`RangeIndex` instead of a :class:`Index` when possible. (:issue:`57824`)
278280
- Performance improvement in :meth:`RangeIndex.join` returning a :class:`RangeIndex` instead of a :class:`Index` when possible. (:issue:`57651`, :issue:`57752`)
279281
- Performance improvement in :meth:`RangeIndex.reindex` returning a :class:`RangeIndex` instead of a :class:`Index` when possible. (:issue:`57647`, :issue:`57752`)

pandas/_libs/meson.build

+23-10
Original file line numberDiff line numberDiff line change
@@ -54,25 +54,37 @@ _intervaltree_helper = custom_target('intervaltree_helper_pxi',
5454
py, tempita, '@INPUT@', '-o', '@OUTDIR@'
5555
]
5656
)
57-
_khash_primitive_helper_dep = declare_dependency(sources: _khash_primitive_helper)
57+
58+
_algos_pxi_dep = declare_dependency(sources: [_algos_take_helper, _algos_common_helper])
59+
_khash_pxi_dep = declare_dependency(sources: _khash_primitive_helper)
60+
_hashtable_pxi_dep = declare_dependency(
61+
sources: [_hashtable_class_helper, _hashtable_func_helper]
62+
)
63+
_index_pxi_dep = declare_dependency(sources: _index_class_helper)
64+
_intervaltree_pxi_dep = declare_dependency(sources: _intervaltree_helper)
65+
_sparse_pxi_dep = declare_dependency(sources: _sparse_op_helper)
66+
5867

5968
subdir('tslibs')
6069

6170
libs_sources = {
6271
# Dict of extension name -> dict of {sources, include_dirs, and deps}
6372
# numpy include dir is implicitly included
64-
'algos': {'sources': ['algos.pyx', _algos_common_helper, _algos_take_helper], 'deps': _khash_primitive_helper_dep},
73+
'algos': {'sources': ['algos.pyx'],
74+
'deps': [_khash_pxi_dep, _algos_pxi_dep]},
6575
'arrays': {'sources': ['arrays.pyx']},
6676
'groupby': {'sources': ['groupby.pyx']},
6777
'hashing': {'sources': ['hashing.pyx']},
68-
'hashtable': {'sources': ['hashtable.pyx', _hashtable_class_helper, _hashtable_func_helper], 'deps': _khash_primitive_helper_dep},
69-
'index': {'sources': ['index.pyx', _index_class_helper], 'deps': _khash_primitive_helper_dep},
78+
'hashtable': {'sources': ['hashtable.pyx'],
79+
'deps': [_khash_pxi_dep, _hashtable_pxi_dep]},
80+
'index': {'sources': ['index.pyx'],
81+
'deps': [_khash_pxi_dep, _index_pxi_dep]},
7082
'indexing': {'sources': ['indexing.pyx']},
7183
'internals': {'sources': ['internals.pyx']},
72-
'interval': {'sources': ['interval.pyx', _intervaltree_helper],
73-
'deps': _khash_primitive_helper_dep},
74-
'join': {'sources': ['join.pyx', _khash_primitive_helper],
75-
'deps': _khash_primitive_helper_dep},
84+
'interval': {'sources': ['interval.pyx'],
85+
'deps': [_khash_pxi_dep, _intervaltree_pxi_dep]},
86+
'join': {'sources': ['join.pyx'],
87+
'deps': [_khash_pxi_dep]},
7688
'lib': {'sources': ['lib.pyx', 'src/parser/tokenizer.c']},
7789
'missing': {'sources': ['missing.pyx']},
7890
'pandas_datetime': {'sources': ['src/vendored/numpy/datetime/np_datetime.c',
@@ -83,7 +95,7 @@ libs_sources = {
8395
'src/parser/io.c',
8496
'src/parser/pd_parser.c']},
8597
'parsers': {'sources': ['parsers.pyx', 'src/parser/tokenizer.c', 'src/parser/io.c'],
86-
'deps': _khash_primitive_helper_dep},
98+
'deps': [_khash_pxi_dep]},
8799
'json': {'sources': ['src/vendored/ujson/python/ujson.c',
88100
'src/vendored/ujson/python/objToJSON.c',
89101
'src/vendored/ujson/python/JSONtoObj.c',
@@ -95,7 +107,8 @@ libs_sources = {
95107
'reshape': {'sources': ['reshape.pyx']},
96108
'sas': {'sources': ['sas.pyx']},
97109
'byteswap': {'sources': ['byteswap.pyx']},
98-
'sparse': {'sources': ['sparse.pyx', _sparse_op_helper]},
110+
'sparse': {'sources': ['sparse.pyx'],
111+
'deps': [_sparse_pxi_dep]},
99112
'tslib': {'sources': ['tslib.pyx']},
100113
'testing': {'sources': ['testing.pyx']},
101114
'writers': {'sources': ['writers.pyx']}

pandas/conftest.py

-4
Original file line numberDiff line numberDiff line change
@@ -173,10 +173,6 @@ def pytest_collection_modifyitems(items, config) -> None:
173173
"DataFrameGroupBy.fillna",
174174
"DataFrameGroupBy.fillna with 'method' is deprecated",
175175
),
176-
(
177-
"DataFrameGroupBy.fillna",
178-
"DataFrame.fillna with 'method' is deprecated",
179-
),
180176
("read_parquet", "Passing a BlockManager to DataFrame is deprecated"),
181177
]
182178

pandas/core/generic.py

+8-37
Original file line numberDiff line numberDiff line change
@@ -6758,7 +6758,6 @@ def fillna(
67586758
self,
67596759
value: Hashable | Mapping | Series | DataFrame = ...,
67606760
*,
6761-
method: FillnaOptions | None = ...,
67626761
axis: Axis | None = ...,
67636762
inplace: Literal[False] = ...,
67646763
limit: int | None = ...,
@@ -6769,7 +6768,6 @@ def fillna(
67696768
self,
67706769
value: Hashable | Mapping | Series | DataFrame = ...,
67716770
*,
6772-
method: FillnaOptions | None = ...,
67736771
axis: Axis | None = ...,
67746772
inplace: Literal[True],
67756773
limit: int | None = ...,
@@ -6780,7 +6778,6 @@ def fillna(
67806778
self,
67816779
value: Hashable | Mapping | Series | DataFrame = ...,
67826780
*,
6783-
method: FillnaOptions | None = ...,
67846781
axis: Axis | None = ...,
67856782
inplace: bool = ...,
67866783
limit: int | None = ...,
@@ -6795,13 +6792,12 @@ def fillna(
67956792
self,
67966793
value: Hashable | Mapping | Series | DataFrame | None = None,
67976794
*,
6798-
method: FillnaOptions | None = None,
67996795
axis: Axis | None = None,
68006796
inplace: bool = False,
68016797
limit: int | None = None,
68026798
) -> Self | None:
68036799
"""
6804-
Fill NA/NaN values using the specified method.
6800+
Fill NA/NaN values with `value`.
68056801
68066802
Parameters
68076803
----------
@@ -6811,15 +6807,6 @@ def fillna(
68116807
each index (for a Series) or column (for a DataFrame). Values not
68126808
in the dict/Series/DataFrame will not be filled. This value cannot
68136809
be a list.
6814-
method : {{'backfill', 'bfill', 'ffill', None}}, default None
6815-
Method to use for filling holes in reindexed Series:
6816-
6817-
* ffill: propagate last valid observation forward to next valid.
6818-
* backfill / bfill: use next valid observation to fill gap.
6819-
6820-
.. deprecated:: 2.1.0
6821-
Use ffill or bfill instead.
6822-
68236810
axis : {axes_single_arg}
68246811
Axis along which to fill missing values. For `Series`
68256812
this parameter is unused and defaults to 0.
@@ -6828,12 +6815,8 @@ def fillna(
68286815
other views on this object (e.g., a no-copy slice for a column in a
68296816
DataFrame).
68306817
limit : int, default None
6831-
If method is specified, this is the maximum number of consecutive
6832-
NaN values to forward/backward fill. In other words, if there is
6833-
a gap with more than this number of consecutive NaNs, it will only
6834-
be partially filled. If method is not specified, this is the
6835-
maximum number of entries along the entire axis where NaNs will be
6836-
filled. Must be greater than 0 if not None.
6818+
This is the maximum number of entries along the entire axis
6819+
where NaNs will be filled. Must be greater than 0 if not None.
68376820
68386821
Returns
68396822
-------
@@ -6918,14 +6901,10 @@ def fillna(
69186901
stacklevel=2,
69196902
)
69206903

6921-
value, method = validate_fillna_kwargs(value, method)
6922-
if method is not None:
6923-
warnings.warn(
6924-
f"{type(self).__name__}.fillna with 'method' is deprecated and "
6925-
"will raise in a future version. Use obj.ffill() or obj.bfill() "
6926-
"instead.",
6927-
FutureWarning,
6928-
stacklevel=find_stack_level(),
6904+
if isinstance(value, (list, tuple)):
6905+
raise TypeError(
6906+
'"value" parameter must be a scalar or dict, but '
6907+
f'you passed a "{type(value).__name__}"'
69296908
)
69306909

69316910
# set the default here, so functions examining the signaure
@@ -6935,15 +6914,7 @@ def fillna(
69356914
axis = self._get_axis_number(axis)
69366915

69376916
if value is None:
6938-
return self._pad_or_backfill(
6939-
# error: Argument 1 to "_pad_or_backfill" of "NDFrame" has
6940-
# incompatible type "Optional[Literal['backfill', 'bfill', 'ffill',
6941-
# 'pad']]"; expected "Literal['ffill', 'bfill', 'pad', 'backfill']"
6942-
method, # type: ignore[arg-type]
6943-
axis=axis,
6944-
limit=limit,
6945-
inplace=inplace,
6946-
)
6917+
raise ValueError("Must specify a fill 'value'.")
69476918
else:
69486919
if self.ndim == 1:
69496920
if isinstance(value, (dict, ABCSeries)):

pandas/core/indexes/range.py

+34-1
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,7 @@ def copy(self, name: Hashable | None = None, deep: bool = False) -> Self:
503503
new_index = self._rename(name=name)
504504
return new_index
505505

506-
def _minmax(self, meth: str) -> int | float:
506+
def _minmax(self, meth: Literal["min", "max"]) -> int | float:
507507
no_steps = len(self) - 1
508508
if no_steps == -1:
509509
return np.nan
@@ -524,6 +524,39 @@ def max(self, axis=None, skipna: bool = True, *args, **kwargs) -> int | float:
524524
nv.validate_max(args, kwargs)
525525
return self._minmax("max")
526526

527+
def _argminmax(
528+
self,
529+
meth: Literal["min", "max"],
530+
axis=None,
531+
skipna: bool = True,
532+
) -> int:
533+
nv.validate_minmax_axis(axis)
534+
if len(self) == 0:
535+
return getattr(super(), f"arg{meth}")(
536+
axis=axis,
537+
skipna=skipna,
538+
)
539+
elif meth == "min":
540+
if self.step > 0:
541+
return 0
542+
else:
543+
return len(self) - 1
544+
elif meth == "max":
545+
if self.step > 0:
546+
return len(self) - 1
547+
else:
548+
return 0
549+
else:
550+
raise ValueError(f"{meth=} must be max or min")
551+
552+
def argmin(self, axis=None, skipna: bool = True, *args, **kwargs) -> int:
553+
nv.validate_argmin(args, kwargs)
554+
return self._argminmax("min", axis=axis, skipna=skipna)
555+
556+
def argmax(self, axis=None, skipna: bool = True, *args, **kwargs) -> int:
557+
nv.validate_argmax(args, kwargs)
558+
return self._argminmax("max", axis=axis, skipna=skipna)
559+
527560
def argsort(self, *args, **kwargs) -> npt.NDArray[np.intp]:
528561
"""
529562
Returns the indices that would sort the index and its

pandas/tests/extension/base/missing.py

+1-7
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,6 @@ def test_fillna_scalar(self, data_missing):
6868
expected = data_missing.fillna(valid)
6969
tm.assert_extension_array_equal(result, expected)
7070

71-
@pytest.mark.filterwarnings(
72-
"ignore:Series.fillna with 'method' is deprecated:FutureWarning"
73-
)
7471
def test_fillna_limit_pad(self, data_missing):
7572
arr = data_missing.take([1, 0, 0, 0, 1])
7673
result = pd.Series(arr).ffill(limit=2)
@@ -99,12 +96,9 @@ def test_ffill_limit_area(
9996
expected = pd.Series(data_missing.take(expected_ilocs))
10097
tm.assert_series_equal(result, expected)
10198

102-
@pytest.mark.filterwarnings(
103-
"ignore:Series.fillna with 'method' is deprecated:FutureWarning"
104-
)
10599
def test_fillna_limit_backfill(self, data_missing):
106100
arr = data_missing.take([1, 0, 0, 0, 1])
107-
result = pd.Series(arr).fillna(method="backfill", limit=2)
101+
result = pd.Series(arr).bfill(limit=2)
108102
expected = pd.Series(data_missing.take([1, 0, 1, 1, 1]))
109103
tm.assert_series_equal(result, expected)
110104

pandas/tests/extension/decimal/test_decimal.py

-9
Original file line numberDiff line numberDiff line change
@@ -187,15 +187,6 @@ def test_ffill_limit_area(
187187
)
188188

189189
def test_fillna_limit_backfill(self, data_missing):
190-
msg = "Series.fillna with 'method' is deprecated"
191-
with tm.assert_produces_warning(
192-
FutureWarning,
193-
match=msg,
194-
check_stacklevel=False,
195-
raise_on_extra_warnings=False,
196-
):
197-
super().test_fillna_limit_backfill(data_missing)
198-
199190
msg = "ExtensionArray.fillna 'method' keyword is deprecated"
200191
with tm.assert_produces_warning(
201192
DeprecationWarning,

pandas/tests/extension/test_sparse.py

-5
Original file line numberDiff line numberDiff line change
@@ -234,11 +234,6 @@ def test_isna(self, data_missing):
234234
expected = SparseArray([False, False], fill_value=False, dtype=expected_dtype)
235235
tm.assert_equal(sarr.isna(), expected)
236236

237-
def test_fillna_limit_backfill(self, data_missing):
238-
warns = FutureWarning
239-
with tm.assert_produces_warning(warns, check_stacklevel=False):
240-
super().test_fillna_limit_backfill(data_missing)
241-
242237
def test_fillna_no_op_returns_copy(self, data, request):
243238
super().test_fillna_no_op_returns_copy(data)
244239

0 commit comments

Comments
 (0)