Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions doc/source/whatsnew/v2.0.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,8 @@ Deprecations
- :meth:`Index.holds_integer` has been deprecated. Use :func:`pandas.api.types.infer_dtype` instead (:issue:`50243`)
- :meth:`Index.is_categorical` has been deprecated. Use :func:`pandas.api.types.is_categorical_dtype` instead (:issue:`50042`)
- :meth:`Index.is_interval` has been deprecated. Use :func:`pandas.api.types.is_intterval_dtype` instead (:issue:`50042`)
- Deprecated ``all`` and ``any`` reductions with ``datetime64`` and :class:`DatetimeTZDtype` dtypes, use e.g. ``(obj != pd.Timestamp(0), tz=obj.tz).all()`` instead (:issue:`34479`)
-

.. ---------------------------------------------------------------------------
.. _whatsnew_200.prior_deprecations:
Expand Down
5 changes: 3 additions & 2 deletions pandas/core/arrays/datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -2034,11 +2034,12 @@ def ceil(
# Reductions

def any(self, *, axis: AxisInt | None = None, skipna: bool = True) -> bool:
# GH#34479 discussion of desired behavior long-term
# GH#34479 the nanops call will issue a FutureWarning for non-td64 dtype
return nanops.nanany(self._ndarray, axis=axis, skipna=skipna, mask=self.isna())

def all(self, *, axis: AxisInt | None = None, skipna: bool = True) -> bool:
# GH#34479 discussion of desired behavior long-term
# GH#34479 the nanops call will issue a FutureWarning for non-td64 dtype

return nanops.nanall(self._ndarray, axis=axis, skipna=skipna, mask=self.isna())

# --------------------------------------------------------------
Expand Down
19 changes: 19 additions & 0 deletions pandas/core/nanops.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
npt,
)
from pandas.compat._optional import import_optional_dependency
from pandas.util._exceptions import find_stack_level

from pandas.core.dtypes.common import (
is_any_int_dtype,
Expand Down Expand Up @@ -529,6 +530,15 @@ def nanany(
>>> nanops.nanany(s)
False
"""
if needs_i8_conversion(values.dtype) and values.dtype.kind != "m":
# GH#34479
warnings.warn(
"'any' with datetime64 dtypes is deprecated and will raise in a "
"future version. Use (obj != pd.Timestamp(0)).any() instead.",
FutureWarning,
stacklevel=find_stack_level(),
)

values, _, _, _, _ = _get_values(values, skipna, fill_value=False, mask=mask)

# For object type, any won't necessarily return
Expand Down Expand Up @@ -575,6 +585,15 @@ def nanall(
>>> nanops.nanall(s)
False
"""
if needs_i8_conversion(values.dtype) and values.dtype.kind != "m":
# GH#34479
warnings.warn(
"'all' with datetime64 dtypes is deprecated and will raise in a "
"future version. Use (obj != pd.Timestamp(0)).all() instead.",
FutureWarning,
stacklevel=find_stack_level(),
)

values, _, _, _, _ = _get_values(values, skipna, fill_value=True, mask=mask)

# For object type, all won't necessarily return
Expand Down
19 changes: 17 additions & 2 deletions pandas/tests/frame/test_reductions.py
Original file line number Diff line number Diff line change
Expand Up @@ -1138,6 +1138,10 @@ def test_any_all_object_dtype(self, axis, bool_agg_func, skipna):
expected = Series([True, True, True, True])
tm.assert_series_equal(result, expected)

# GH#50947 deprecates this but it is not emitting a warning in some builds.
@pytest.mark.filterwarnings(
"ignore:'any' with datetime64 dtypes is deprecated.*:FutureWarning"
)
def test_any_datetime(self):

# GH 23070
Expand All @@ -1151,6 +1155,7 @@ def test_any_datetime(self):
df = DataFrame({"A": float_data, "B": datetime_data})

result = df.any(axis=1)

expected = Series([True, True, True, False])
tm.assert_series_equal(result, expected)

Expand Down Expand Up @@ -1245,12 +1250,22 @@ def test_any_all_np_func(self, func, data, expected):
):
getattr(DataFrame(data), func.__name__)(axis=None)
else:
result = func(data)
msg = "'(any|all)' with datetime64 dtypes is deprecated"
if data.dtypes.apply(lambda x: x.kind == "M").any():
warn = FutureWarning
else:
warn = None

with tm.assert_produces_warning(warn, match=msg, check_stacklevel=False):
# GH#34479
result = func(data)
assert isinstance(result, np.bool_)
assert result.item() is expected

# method version
result = getattr(DataFrame(data), func.__name__)(axis=None)
with tm.assert_produces_warning(warn, match=msg):
# GH#34479
result = getattr(DataFrame(data), func.__name__)(axis=None)
assert isinstance(result, np.bool_)
assert result.item() is expected

Expand Down
29 changes: 17 additions & 12 deletions pandas/tests/reductions/test_reductions.py
Original file line number Diff line number Diff line change
Expand Up @@ -985,27 +985,32 @@ def test_any_all_datetimelike(self):
ser = Series(dta)
df = DataFrame(ser)

assert dta.all()
assert dta.any()
msg = "'(any|all)' with datetime64 dtypes is deprecated"
with tm.assert_produces_warning(FutureWarning, match=msg):
# GH#34479
assert dta.all()
assert dta.any()

assert ser.all()
assert ser.any()
assert ser.all()
assert ser.any()

assert df.any().all()
assert df.all().all()
assert df.any().all()
assert df.all().all()

dta = dta.tz_localize("UTC")
ser = Series(dta)
df = DataFrame(ser)

assert dta.all()
assert dta.any()
with tm.assert_produces_warning(FutureWarning, match=msg):
# GH#34479
assert dta.all()
assert dta.any()

assert ser.all()
assert ser.any()
assert ser.all()
assert ser.any()

assert df.any().all()
assert df.all().all()
assert df.any().all()
assert df.all().all()

tda = dta - dta[0]
ser = Series(tda)
Expand Down