Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main' into ref/is_range_indexe…
Browse files Browse the repository at this point in the history
…r/step
  • Loading branch information
mroeschke committed Mar 14, 2024
2 parents 997416f + d2bf501 commit d3ae4e9
Show file tree
Hide file tree
Showing 14 changed files with 168 additions and 215 deletions.
36 changes: 30 additions & 6 deletions doc/source/whatsnew/v0.10.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -242,18 +242,42 @@ labeled the aggregated group with the end of the interval: the next day).
- Calling ``fillna`` on Series or DataFrame with no arguments is no longer
valid code. You must either specify a fill value or an interpolation method:

.. ipython:: python
:okwarning:
.. code-block:: ipython
s = pd.Series([np.nan, 1.0, 2.0, np.nan, 4])
s
s.fillna(0)
s.fillna(method="pad")
In [6]: s = pd.Series([np.nan, 1.0, 2.0, np.nan, 4])
In [7]: s
Out[7]:
0 NaN
1 1.0
2 2.0
3 NaN
4 4.0
dtype: float64
In [8]: s.fillna(0)
Out[8]:
0 0.0
1 1.0
2 2.0
3 0.0
4 4.0
dtype: float64
In [9]: s.fillna(method="pad")
Out[9]:
0 NaN
1 1.0
2 2.0
3 2.0
4 4.0
dtype: float64
Convenience methods ``ffill`` and ``bfill`` have been added:

.. ipython:: python
s = pd.Series([np.nan, 1.0, 2.0, np.nan, 4])
s.ffill()
Expand Down
2 changes: 2 additions & 0 deletions doc/source/whatsnew/v3.0.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ Removal of prior version deprecations/changes
- 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`)
- Removed deprecated argument ``obj`` in :meth:`.DataFrameGroupBy.get_group` and :meth:`.SeriesGroupBy.get_group` (:issue:`53545`)
- Removed deprecated behavior of :meth:`Series.agg` using :meth:`Series.apply` (:issue:`53325`)
- Removed deprecated keyword ``method`` on :meth:`Series.fillna`, :meth:`DataFrame.fillna` (:issue:`57760`)
- Removed option ``mode.use_inf_as_na``, convert inf entries to ``NaN`` before instead (:issue:`51684`)
- Removed support for :class:`DataFrame` in :meth:`DataFrame.from_records`(:issue:`51697`)
- Removed support for ``errors="ignore"`` in :func:`to_datetime`, :func:`to_timedelta` and :func:`to_numeric` (:issue:`55734`)
Expand Down Expand Up @@ -274,6 +275,7 @@ Performance improvements
- Performance improvement in :meth:`MultiIndex.equals` for equal length indexes (:issue:`56990`)
- 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`)
- Performance improvement in :meth:`RangeIndex.append` when appending the same index (:issue:`57252`)
- Performance improvement in :meth:`RangeIndex.argmin` and :meth:`RangeIndex.argmax` (:issue:`57823`)
- Performance improvement in :meth:`RangeIndex.round` returning a :class:`RangeIndex` instead of a :class:`Index` when possible. (:issue:`57824`)
- Performance improvement in :meth:`RangeIndex.join` returning a :class:`RangeIndex` instead of a :class:`Index` when possible. (:issue:`57651`, :issue:`57752`)
- Performance improvement in :meth:`RangeIndex.reindex` returning a :class:`RangeIndex` instead of a :class:`Index` when possible. (:issue:`57647`, :issue:`57752`)
Expand Down
33 changes: 23 additions & 10 deletions pandas/_libs/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -54,25 +54,37 @@ _intervaltree_helper = custom_target('intervaltree_helper_pxi',
py, tempita, '@INPUT@', '-o', '@OUTDIR@'
]
)
_khash_primitive_helper_dep = declare_dependency(sources: _khash_primitive_helper)

_algos_pxi_dep = declare_dependency(sources: [_algos_take_helper, _algos_common_helper])
_khash_pxi_dep = declare_dependency(sources: _khash_primitive_helper)
_hashtable_pxi_dep = declare_dependency(
sources: [_hashtable_class_helper, _hashtable_func_helper]
)
_index_pxi_dep = declare_dependency(sources: _index_class_helper)
_intervaltree_pxi_dep = declare_dependency(sources: _intervaltree_helper)
_sparse_pxi_dep = declare_dependency(sources: _sparse_op_helper)


subdir('tslibs')

libs_sources = {
# Dict of extension name -> dict of {sources, include_dirs, and deps}
# numpy include dir is implicitly included
'algos': {'sources': ['algos.pyx', _algos_common_helper, _algos_take_helper], 'deps': _khash_primitive_helper_dep},
'algos': {'sources': ['algos.pyx'],
'deps': [_khash_pxi_dep, _algos_pxi_dep]},
'arrays': {'sources': ['arrays.pyx']},
'groupby': {'sources': ['groupby.pyx']},
'hashing': {'sources': ['hashing.pyx']},
'hashtable': {'sources': ['hashtable.pyx', _hashtable_class_helper, _hashtable_func_helper], 'deps': _khash_primitive_helper_dep},
'index': {'sources': ['index.pyx', _index_class_helper], 'deps': _khash_primitive_helper_dep},
'hashtable': {'sources': ['hashtable.pyx'],
'deps': [_khash_pxi_dep, _hashtable_pxi_dep]},
'index': {'sources': ['index.pyx'],
'deps': [_khash_pxi_dep, _index_pxi_dep]},
'indexing': {'sources': ['indexing.pyx']},
'internals': {'sources': ['internals.pyx']},
'interval': {'sources': ['interval.pyx', _intervaltree_helper],
'deps': _khash_primitive_helper_dep},
'join': {'sources': ['join.pyx', _khash_primitive_helper],
'deps': _khash_primitive_helper_dep},
'interval': {'sources': ['interval.pyx'],
'deps': [_khash_pxi_dep, _intervaltree_pxi_dep]},
'join': {'sources': ['join.pyx'],
'deps': [_khash_pxi_dep]},
'lib': {'sources': ['lib.pyx', 'src/parser/tokenizer.c']},
'missing': {'sources': ['missing.pyx']},
'pandas_datetime': {'sources': ['src/vendored/numpy/datetime/np_datetime.c',
Expand All @@ -83,7 +95,7 @@ libs_sources = {
'src/parser/io.c',
'src/parser/pd_parser.c']},
'parsers': {'sources': ['parsers.pyx', 'src/parser/tokenizer.c', 'src/parser/io.c'],
'deps': _khash_primitive_helper_dep},
'deps': [_khash_pxi_dep]},
'json': {'sources': ['src/vendored/ujson/python/ujson.c',
'src/vendored/ujson/python/objToJSON.c',
'src/vendored/ujson/python/JSONtoObj.c',
Expand All @@ -95,7 +107,8 @@ libs_sources = {
'reshape': {'sources': ['reshape.pyx']},
'sas': {'sources': ['sas.pyx']},
'byteswap': {'sources': ['byteswap.pyx']},
'sparse': {'sources': ['sparse.pyx', _sparse_op_helper]},
'sparse': {'sources': ['sparse.pyx'],
'deps': [_sparse_pxi_dep]},
'tslib': {'sources': ['tslib.pyx']},
'testing': {'sources': ['testing.pyx']},
'writers': {'sources': ['writers.pyx']}
Expand Down
4 changes: 0 additions & 4 deletions pandas/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,6 @@ def pytest_collection_modifyitems(items, config) -> None:
"DataFrameGroupBy.fillna",
"DataFrameGroupBy.fillna with 'method' is deprecated",
),
(
"DataFrameGroupBy.fillna",
"DataFrame.fillna with 'method' is deprecated",
),
("read_parquet", "Passing a BlockManager to DataFrame is deprecated"),
]

Expand Down
45 changes: 8 additions & 37 deletions pandas/core/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -6758,7 +6758,6 @@ def fillna(
self,
value: Hashable | Mapping | Series | DataFrame = ...,
*,
method: FillnaOptions | None = ...,
axis: Axis | None = ...,
inplace: Literal[False] = ...,
limit: int | None = ...,
Expand All @@ -6769,7 +6768,6 @@ def fillna(
self,
value: Hashable | Mapping | Series | DataFrame = ...,
*,
method: FillnaOptions | None = ...,
axis: Axis | None = ...,
inplace: Literal[True],
limit: int | None = ...,
Expand All @@ -6780,7 +6778,6 @@ def fillna(
self,
value: Hashable | Mapping | Series | DataFrame = ...,
*,
method: FillnaOptions | None = ...,
axis: Axis | None = ...,
inplace: bool = ...,
limit: int | None = ...,
Expand All @@ -6795,13 +6792,12 @@ def fillna(
self,
value: Hashable | Mapping | Series | DataFrame | None = None,
*,
method: FillnaOptions | None = None,
axis: Axis | None = None,
inplace: bool = False,
limit: int | None = None,
) -> Self | None:
"""
Fill NA/NaN values using the specified method.
Fill NA/NaN values with `value`.
Parameters
----------
Expand All @@ -6811,15 +6807,6 @@ def fillna(
each index (for a Series) or column (for a DataFrame). Values not
in the dict/Series/DataFrame will not be filled. This value cannot
be a list.
method : {{'backfill', 'bfill', 'ffill', None}}, default None
Method to use for filling holes in reindexed Series:
* ffill: propagate last valid observation forward to next valid.
* backfill / bfill: use next valid observation to fill gap.
.. deprecated:: 2.1.0
Use ffill or bfill instead.
axis : {axes_single_arg}
Axis along which to fill missing values. For `Series`
this parameter is unused and defaults to 0.
Expand All @@ -6828,12 +6815,8 @@ def fillna(
other views on this object (e.g., a no-copy slice for a column in a
DataFrame).
limit : int, default None
If method is specified, this is the maximum number of consecutive
NaN values to forward/backward fill. In other words, if there is
a gap with more than this number of consecutive NaNs, it will only
be partially filled. If method is not specified, this is the
maximum number of entries along the entire axis where NaNs will be
filled. Must be greater than 0 if not None.
This is the maximum number of entries along the entire axis
where NaNs will be filled. Must be greater than 0 if not None.
Returns
-------
Expand Down Expand Up @@ -6918,14 +6901,10 @@ def fillna(
stacklevel=2,
)

value, method = validate_fillna_kwargs(value, method)
if method is not None:
warnings.warn(
f"{type(self).__name__}.fillna with 'method' is deprecated and "
"will raise in a future version. Use obj.ffill() or obj.bfill() "
"instead.",
FutureWarning,
stacklevel=find_stack_level(),
if isinstance(value, (list, tuple)):
raise TypeError(
'"value" parameter must be a scalar or dict, but '
f'you passed a "{type(value).__name__}"'
)

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

if value is None:
return self._pad_or_backfill(
# error: Argument 1 to "_pad_or_backfill" of "NDFrame" has
# incompatible type "Optional[Literal['backfill', 'bfill', 'ffill',
# 'pad']]"; expected "Literal['ffill', 'bfill', 'pad', 'backfill']"
method, # type: ignore[arg-type]
axis=axis,
limit=limit,
inplace=inplace,
)
raise ValueError("Must specify a fill 'value'.")
else:
if self.ndim == 1:
if isinstance(value, (dict, ABCSeries)):
Expand Down
35 changes: 34 additions & 1 deletion pandas/core/indexes/range.py
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,7 @@ def copy(self, name: Hashable | None = None, deep: bool = False) -> Self:
new_index = self._rename(name=name)
return new_index

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

def _argminmax(
self,
meth: Literal["min", "max"],
axis=None,
skipna: bool = True,
) -> int:
nv.validate_minmax_axis(axis)
if len(self) == 0:
return getattr(super(), f"arg{meth}")(
axis=axis,
skipna=skipna,
)
elif meth == "min":
if self.step > 0:
return 0
else:
return len(self) - 1
elif meth == "max":
if self.step > 0:
return len(self) - 1
else:
return 0
else:
raise ValueError(f"{meth=} must be max or min")

def argmin(self, axis=None, skipna: bool = True, *args, **kwargs) -> int:
nv.validate_argmin(args, kwargs)
return self._argminmax("min", axis=axis, skipna=skipna)

def argmax(self, axis=None, skipna: bool = True, *args, **kwargs) -> int:
nv.validate_argmax(args, kwargs)
return self._argminmax("max", axis=axis, skipna=skipna)

def argsort(self, *args, **kwargs) -> npt.NDArray[np.intp]:
"""
Returns the indices that would sort the index and its
Expand Down
8 changes: 1 addition & 7 deletions pandas/tests/extension/base/missing.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,6 @@ def test_fillna_scalar(self, data_missing):
expected = data_missing.fillna(valid)
tm.assert_extension_array_equal(result, expected)

@pytest.mark.filterwarnings(
"ignore:Series.fillna with 'method' is deprecated:FutureWarning"
)
def test_fillna_limit_pad(self, data_missing):
arr = data_missing.take([1, 0, 0, 0, 1])
result = pd.Series(arr).ffill(limit=2)
Expand Down Expand Up @@ -99,12 +96,9 @@ def test_ffill_limit_area(
expected = pd.Series(data_missing.take(expected_ilocs))
tm.assert_series_equal(result, expected)

@pytest.mark.filterwarnings(
"ignore:Series.fillna with 'method' is deprecated:FutureWarning"
)
def test_fillna_limit_backfill(self, data_missing):
arr = data_missing.take([1, 0, 0, 0, 1])
result = pd.Series(arr).fillna(method="backfill", limit=2)
result = pd.Series(arr).bfill(limit=2)
expected = pd.Series(data_missing.take([1, 0, 1, 1, 1]))
tm.assert_series_equal(result, expected)

Expand Down
9 changes: 0 additions & 9 deletions pandas/tests/extension/decimal/test_decimal.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,15 +187,6 @@ def test_ffill_limit_area(
)

def test_fillna_limit_backfill(self, data_missing):
msg = "Series.fillna with 'method' is deprecated"
with tm.assert_produces_warning(
FutureWarning,
match=msg,
check_stacklevel=False,
raise_on_extra_warnings=False,
):
super().test_fillna_limit_backfill(data_missing)

msg = "ExtensionArray.fillna 'method' keyword is deprecated"
with tm.assert_produces_warning(
DeprecationWarning,
Expand Down
5 changes: 0 additions & 5 deletions pandas/tests/extension/test_sparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,11 +234,6 @@ def test_isna(self, data_missing):
expected = SparseArray([False, False], fill_value=False, dtype=expected_dtype)
tm.assert_equal(sarr.isna(), expected)

def test_fillna_limit_backfill(self, data_missing):
warns = FutureWarning
with tm.assert_produces_warning(warns, check_stacklevel=False):
super().test_fillna_limit_backfill(data_missing)

def test_fillna_no_op_returns_copy(self, data, request):
super().test_fillna_no_op_returns_copy(data)

Expand Down
Loading

0 comments on commit d3ae4e9

Please sign in to comment.