diff --git a/pandas/core/algorithms.py b/pandas/core/algorithms.py index 23ba0ac1c737e..26099a94834e8 100644 --- a/pandas/core/algorithms.py +++ b/pandas/core/algorithms.py @@ -29,7 +29,6 @@ is_complex_dtype, is_datetime64_any_dtype, is_datetime64_ns_dtype, - is_datetimelike, is_extension_array_dtype, is_float_dtype, is_integer, @@ -834,7 +833,7 @@ def mode(values, dropna: bool = True) -> ABCSeries: return Series(values.values.mode(dropna=dropna), name=values.name) return values.mode(dropna=dropna) - if dropna and is_datetimelike(values): + if dropna and needs_i8_conversion(values.dtype): mask = values.isnull() values = values[~mask] diff --git a/pandas/core/arrays/categorical.py b/pandas/core/arrays/categorical.py index ce174baa66a97..73716fdeb42bb 100644 --- a/pandas/core/arrays/categorical.py +++ b/pandas/core/arrays/categorical.py @@ -25,7 +25,6 @@ ensure_platform_int, is_categorical_dtype, is_datetime64_dtype, - is_datetimelike, is_dict_like, is_dtype_equal, is_extension_array_dtype, @@ -37,6 +36,7 @@ is_scalar, is_sequence, is_timedelta64_dtype, + needs_i8_conversion, ) from pandas.core.dtypes.dtypes import CategoricalDtype from pandas.core.dtypes.generic import ABCDataFrame, ABCIndexClass, ABCSeries @@ -1533,7 +1533,7 @@ def get_values(self): def _internal_get_values(self): # if we are a datetime and period index, return Index to keep metadata - if is_datetimelike(self.categories): + if needs_i8_conversion(self.categories): return self.categories.take(self._codes, fill_value=np.nan) elif is_integer_dtype(self.categories) and -1 in self._codes: return self.categories.astype("object").take(self._codes, fill_value=np.nan) diff --git a/pandas/core/base.py b/pandas/core/base.py index 61dc5f35cadf7..eeb0b72e301dd 100644 --- a/pandas/core/base.py +++ b/pandas/core/base.py @@ -21,7 +21,6 @@ is_categorical_dtype, is_datetime64_ns_dtype, is_datetime64tz_dtype, - is_datetimelike, is_extension_array_dtype, is_extension_type, is_list_like, @@ -1172,7 +1171,7 @@ def tolist(self): -------- numpy.ndarray.tolist """ - if is_datetimelike(self._values): + if self.dtype.kind in ["m", "M"]: return [com.maybe_box_datetimelike(x) for x in self._values] elif is_extension_array_dtype(self._values): return list(self._values) @@ -1194,7 +1193,7 @@ def __iter__(self): iterator """ # We are explicitly making element iterators. - if is_datetimelike(self._values): + if self.dtype.kind in ["m", "M"]: return map(com.maybe_box_datetimelike, self._values) elif is_extension_array_dtype(self._values): return iter(self._values) diff --git a/pandas/core/dtypes/cast.py b/pandas/core/dtypes/cast.py index fad80d6bf5745..bbed3a545e478 100644 --- a/pandas/core/dtypes/cast.py +++ b/pandas/core/dtypes/cast.py @@ -27,7 +27,6 @@ is_datetime64_ns_dtype, is_datetime64tz_dtype, is_datetime_or_timedelta_dtype, - is_datetimelike, is_dtype_equal, is_extension_array_dtype, is_extension_type, @@ -274,7 +273,7 @@ def maybe_upcast_putmask(result: np.ndarray, mask: np.ndarray, other): # in np.place: # NaN -> NaT # integer or integer array -> date-like array - if is_datetimelike(result.dtype): + if result.dtype.kind in ["m", "M"]: if is_scalar(other): if isna(other): other = result.dtype.type("nat") diff --git a/pandas/core/dtypes/common.py b/pandas/core/dtypes/common.py index 2a46d335ff512..c3e98d4009135 100644 --- a/pandas/core/dtypes/common.py +++ b/pandas/core/dtypes/common.py @@ -799,54 +799,6 @@ def is_datetime_arraylike(arr): return getattr(arr, "inferred_type", None) == "datetime" -def is_datetimelike(arr): - """ - Check whether an array-like is a datetime-like array-like. - - Acceptable datetime-like objects are (but not limited to) datetime - indices, periodic indices, and timedelta indices. - - Parameters - ---------- - arr : array-like - The array-like to check. - - Returns - ------- - boolean - Whether or not the array-like is a datetime-like array-like. - - Examples - -------- - >>> is_datetimelike([1, 2, 3]) - False - >>> is_datetimelike(pd.Index([1, 2, 3])) - False - >>> is_datetimelike(pd.DatetimeIndex([1, 2, 3])) - True - >>> is_datetimelike(pd.DatetimeIndex([1, 2, 3], tz="US/Eastern")) - True - >>> is_datetimelike(pd.PeriodIndex([], freq="A")) - True - >>> is_datetimelike(np.array([], dtype=np.datetime64)) - True - >>> is_datetimelike(pd.Series([], dtype="timedelta64[ns]")) - True - >>> - >>> dtype = DatetimeTZDtype("ns", tz="US/Eastern") - >>> s = pd.Series([], dtype=dtype) - >>> is_datetimelike(s) - True - """ - - return ( - is_datetime64_dtype(arr) - or is_datetime64tz_dtype(arr) - or is_timedelta64_dtype(arr) - or isinstance(arr, ABCPeriodIndex) - ) - - def is_dtype_equal(source, target): """ Check if two dtypes are equal. @@ -1446,9 +1398,8 @@ def is_numeric(x): """ return is_integer_dtype(x) or is_float_dtype(x) - is_datetimelike = needs_i8_conversion - return (is_datetimelike(a) and is_numeric(b)) or ( - is_datetimelike(b) and is_numeric(a) + return (needs_i8_conversion(a) and is_numeric(b)) or ( + needs_i8_conversion(b) and is_numeric(a) ) diff --git a/pandas/core/dtypes/missing.py b/pandas/core/dtypes/missing.py index 322011eb8e263..22e38a805f996 100644 --- a/pandas/core/dtypes/missing.py +++ b/pandas/core/dtypes/missing.py @@ -17,7 +17,6 @@ is_complex_dtype, is_datetime64_dtype, is_datetime64tz_dtype, - is_datetimelike, is_datetimelike_v_numeric, is_dtype_equal, is_extension_array_dtype, @@ -494,7 +493,7 @@ def _infer_fill_value(val): if not is_list_like(val): val = [val] val = np.array(val, copy=False) - if is_datetimelike(val): + if needs_i8_conversion(val): return np.array("NaT", dtype=val.dtype) elif is_object_dtype(val.dtype): dtype = lib.infer_dtype(ensure_object(val), skipna=False) diff --git a/pandas/core/groupby/generic.py b/pandas/core/groupby/generic.py index 511b87dab087e..3b8c3148f5177 100644 --- a/pandas/core/groupby/generic.py +++ b/pandas/core/groupby/generic.py @@ -40,7 +40,6 @@ ensure_int64, ensure_platform_int, is_bool, - is_datetimelike, is_dict_like, is_integer_dtype, is_interval_dtype, @@ -48,6 +47,7 @@ is_numeric_dtype, is_object_dtype, is_scalar, + needs_i8_conversion, ) from pandas.core.dtypes.missing import _isna_ndarraylike, isna, notna @@ -1287,7 +1287,7 @@ def first_not_none(values): # if we have date/time like in the original, then coerce dates # as we are stacking can easily have object dtypes here so = self._selected_obj - if so.ndim == 2 and so.dtypes.apply(is_datetimelike).any(): + if so.ndim == 2 and so.dtypes.apply(needs_i8_conversion).any(): result = _recast_datetimelike_result(result) else: result = result._convert(datetime=True) diff --git a/pandas/core/reshape/merge.py b/pandas/core/reshape/merge.py index a189b2cd1ab84..30857a51debd1 100644 --- a/pandas/core/reshape/merge.py +++ b/pandas/core/reshape/merge.py @@ -24,7 +24,6 @@ is_bool_dtype, is_categorical_dtype, is_datetime64tz_dtype, - is_datetimelike, is_dtype_equal, is_extension_array_dtype, is_float_dtype, @@ -1120,9 +1119,9 @@ def _maybe_coerce_merge_keys(self): raise ValueError(msg) # datetimelikes must match exactly - elif is_datetimelike(lk) and not is_datetimelike(rk): + elif needs_i8_conversion(lk) and not needs_i8_conversion(rk): raise ValueError(msg) - elif not is_datetimelike(lk) and is_datetimelike(rk): + elif not needs_i8_conversion(lk) and needs_i8_conversion(rk): raise ValueError(msg) elif is_datetime64tz_dtype(lk) and not is_datetime64tz_dtype(rk): raise ValueError(msg) @@ -1637,7 +1636,7 @@ def _get_merge_keys(self): ) ) - if is_datetimelike(lt): + if needs_i8_conversion(lt): if not isinstance(self.tolerance, datetime.timedelta): raise MergeError(msg) if self.tolerance < Timedelta(0): diff --git a/pandas/core/series.py b/pandas/core/series.py index 73a05b4cdfa66..6440d2f03cf1a 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -25,7 +25,6 @@ is_categorical, is_categorical_dtype, is_datetime64_dtype, - is_datetimelike, is_dict_like, is_extension_array_dtype, is_extension_type, @@ -2886,7 +2885,7 @@ def combine_first(self, other): new_index = self.index.union(other.index) this = self.reindex(new_index, copy=False) other = other.reindex(new_index, copy=False) - if is_datetimelike(this) and not is_datetimelike(other): + if this.dtype.kind == "M" and other.dtype.kind != "M": other = to_datetime(other) return this.where(notna(this), other) diff --git a/pandas/tests/dtypes/test_common.py b/pandas/tests/dtypes/test_common.py index 894d6a40280b7..5e409b85049ae 100644 --- a/pandas/tests/dtypes/test_common.py +++ b/pandas/tests/dtypes/test_common.py @@ -309,21 +309,6 @@ def test_is_datetime_arraylike(): assert com.is_datetime_arraylike(pd.DatetimeIndex([1, 2, 3])) -def test_is_datetimelike(): - assert not com.is_datetimelike([1, 2, 3]) - assert not com.is_datetimelike(pd.Index([1, 2, 3])) - - assert com.is_datetimelike(pd.DatetimeIndex([1, 2, 3])) - assert com.is_datetimelike(pd.PeriodIndex([], freq="A")) - assert com.is_datetimelike(np.array([], dtype=np.datetime64)) - assert com.is_datetimelike(pd.Series([], dtype="timedelta64[ns]")) - assert com.is_datetimelike(pd.DatetimeIndex(["2000"], tz="US/Eastern")) - - dtype = DatetimeTZDtype("ns", tz="US/Eastern") - s = pd.Series([], dtype=dtype) - assert com.is_datetimelike(s) - - integer_dtypes = [] # type: List