From 607f85355a26181b1f869f477c81244ea06783cb Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Sun, 25 Nov 2018 15:06:07 -0800 Subject: [PATCH 01/18] remove unused maybe_convert_scalar --- pandas/core/dtypes/cast.py | 14 -------------- pandas/tests/dtypes/test_cast.py | 31 ------------------------------- 2 files changed, 45 deletions(-) diff --git a/pandas/core/dtypes/cast.py b/pandas/core/dtypes/cast.py index 3c5f8830441f7..db59b21d6d57e 100644 --- a/pandas/core/dtypes/cast.py +++ b/pandas/core/dtypes/cast.py @@ -578,20 +578,6 @@ def maybe_convert_string_to_object(values): return values -def maybe_convert_scalar(values): - """ - Convert a python scalar to the appropriate numpy dtype if possible - This avoids numpy directly converting according to platform preferences - """ - if is_scalar(values): - dtype, values = infer_dtype_from_scalar(values) - try: - values = dtype(values) - except TypeError: - pass - return values - - def coerce_indexer_dtype(indexer, categories): """ coerce the indexer input array to the smallest dtype possible """ length = len(categories) diff --git a/pandas/tests/dtypes/test_cast.py b/pandas/tests/dtypes/test_cast.py index 0d6382424ccf5..9bc12333fefaf 100644 --- a/pandas/tests/dtypes/test_cast.py +++ b/pandas/tests/dtypes/test_cast.py @@ -20,7 +20,6 @@ infer_dtype_from_scalar, infer_dtype_from_array, maybe_convert_string_to_object, - maybe_convert_scalar, find_common_type, construct_1d_object_array_from_listlike, construct_1d_ndarray_preserving_na, @@ -268,36 +267,6 @@ def test_maybe_convert_string_to_array(self): tm.assert_numpy_array_equal(result, np.array(['x', 2], dtype=object)) assert result.dtype == object - def test_maybe_convert_scalar(self): - - # pass thru - result = maybe_convert_scalar('x') - assert result == 'x' - result = maybe_convert_scalar(np.array([1])) - assert result == np.array([1]) - - # leave scalar dtype - result = maybe_convert_scalar(np.int64(1)) - assert result == np.int64(1) - result = maybe_convert_scalar(np.int32(1)) - assert result == np.int32(1) - result = maybe_convert_scalar(np.float32(1)) - assert result == np.float32(1) - result = maybe_convert_scalar(np.int64(1)) - assert result == np.float64(1) - - # coerce - result = maybe_convert_scalar(1) - assert result == np.int64(1) - result = maybe_convert_scalar(1.0) - assert result == np.float64(1) - result = maybe_convert_scalar(Timestamp('20130101')) - assert result == Timestamp('20130101').value - result = maybe_convert_scalar(datetime(2013, 1, 1)) - assert result == Timestamp('20130101').value - result = maybe_convert_scalar(Timedelta('1 day 1 min')) - assert result == Timedelta('1 day 1 min').value - def test_maybe_infer_to_datetimelike(self): # GH16362 # pandas=0.20.1 raises IndexError: tuple index out of range From 1e95d48953e27fe8b8e1ca045ff860050717e850 Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Sun, 25 Nov 2018 15:07:28 -0800 Subject: [PATCH 02/18] remove unused maybe_convert_string_to_object --- pandas/core/dtypes/cast.py | 14 -------------- pandas/tests/dtypes/test_cast.py | 26 -------------------------- 2 files changed, 40 deletions(-) diff --git a/pandas/core/dtypes/cast.py b/pandas/core/dtypes/cast.py index db59b21d6d57e..791b3b6421e2b 100644 --- a/pandas/core/dtypes/cast.py +++ b/pandas/core/dtypes/cast.py @@ -564,20 +564,6 @@ def invalidate_string_dtypes(dtype_set): raise TypeError("string dtypes are not allowed, use 'object' instead") -def maybe_convert_string_to_object(values): - """ - - Convert string-like and string-like array to convert object dtype. - This is to avoid numpy to handle the array as str dtype. - """ - if isinstance(values, string_types): - values = np.array([values], dtype=object) - elif (isinstance(values, np.ndarray) and - issubclass(values.dtype.type, (np.string_, np.unicode_))): - values = values.astype(object) - return values - - def coerce_indexer_dtype(indexer, categories): """ coerce the indexer input array to the smallest dtype possible """ length = len(categories) diff --git a/pandas/tests/dtypes/test_cast.py b/pandas/tests/dtypes/test_cast.py index 9bc12333fefaf..fcdcf96098f16 100644 --- a/pandas/tests/dtypes/test_cast.py +++ b/pandas/tests/dtypes/test_cast.py @@ -19,7 +19,6 @@ cast_scalar_to_array, infer_dtype_from_scalar, infer_dtype_from_array, - maybe_convert_string_to_object, find_common_type, construct_1d_object_array_from_listlike, construct_1d_ndarray_preserving_na, @@ -242,31 +241,6 @@ def test_cast_scalar_to_array(self): class TestMaybe(object): - def test_maybe_convert_string_to_array(self): - result = maybe_convert_string_to_object('x') - tm.assert_numpy_array_equal(result, np.array(['x'], dtype=object)) - assert result.dtype == object - - result = maybe_convert_string_to_object(1) - assert result == 1 - - arr = np.array(['x', 'y'], dtype=str) - result = maybe_convert_string_to_object(arr) - tm.assert_numpy_array_equal(result, np.array(['x', 'y'], dtype=object)) - assert result.dtype == object - - # unicode - arr = np.array(['x', 'y']).astype('U') - result = maybe_convert_string_to_object(arr) - tm.assert_numpy_array_equal(result, np.array(['x', 'y'], dtype=object)) - assert result.dtype == object - - # object - arr = np.array(['x', 2], dtype=object) - result = maybe_convert_string_to_object(arr) - tm.assert_numpy_array_equal(result, np.array(['x', 2], dtype=object)) - assert result.dtype == object - def test_maybe_infer_to_datetimelike(self): # GH16362 # pandas=0.20.1 raises IndexError: tuple index out of range From 714c2873443a27a8e411922a4a39efd6ab976ac5 Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Sun, 25 Nov 2018 15:13:15 -0800 Subject: [PATCH 03/18] remove deprecated is_floating_dtype --- doc/source/whatsnew/v0.24.0.rst | 1 + pandas/core/dtypes/common.py | 16 ---------------- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/doc/source/whatsnew/v0.24.0.rst b/doc/source/whatsnew/v0.24.0.rst index 48a3bfdab62c9..2e266443a6421 100644 --- a/doc/source/whatsnew/v0.24.0.rst +++ b/doc/source/whatsnew/v0.24.0.rst @@ -1124,6 +1124,7 @@ Removal of prior version deprecations/changes - :meth:`SparseSeries.to_dense` has dropped the ``sparse_only`` parameter (:issue:`14686`) - :meth:`DataFrame.astype` and :meth:`Series.astype` have renamed the ``raise_on_error`` argument to ``errors`` (:issue:`14967`) - ``is_sequence``, ``is_any_int_dtype``, and ``is_floating_dtype`` have been removed from ``pandas.api.types`` (:issue:`16163`, :issue:`16189`) +- ``is_floating_dtype`` has been removed (:issue:`????`) .. _whatsnew_0240.performance: diff --git a/pandas/core/dtypes/common.py b/pandas/core/dtypes/common.py index de7e453e80d85..5af37abd303a0 100644 --- a/pandas/core/dtypes/common.py +++ b/pandas/core/dtypes/common.py @@ -1619,22 +1619,6 @@ def is_float_dtype(arr_or_dtype): return issubclass(tipo, np.floating) -def is_floating_dtype(arr_or_dtype): - """Check whether the provided array or dtype is an instance of - numpy's float dtype. - - .. deprecated:: 0.20.0 - - Unlike, `is_float_dtype`, this check is a lot stricter, as it requires - `isinstance` of `np.floating` and not `issubclass`. - """ - - if arr_or_dtype is None: - return False - tipo = _get_dtype_type(arr_or_dtype) - return isinstance(tipo, np.floating) - - def is_bool_dtype(arr_or_dtype): """ Check whether the provided array or dtype is of a boolean dtype. From ba6ef3d8bd42341901b9e562cc71d746488b0882 Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Sun, 25 Nov 2018 15:32:03 -0800 Subject: [PATCH 04/18] deprecate is_period --- doc/source/whatsnew/v0.24.0.rst | 1 + pandas/core/dtypes/common.py | 9 +++++++++ pandas/tests/dtypes/test_common.py | 8 +++++--- pandas/tests/dtypes/test_dtypes.py | 12 ++++++++---- 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/doc/source/whatsnew/v0.24.0.rst b/doc/source/whatsnew/v0.24.0.rst index 2e266443a6421..e77482a826419 100644 --- a/doc/source/whatsnew/v0.24.0.rst +++ b/doc/source/whatsnew/v0.24.0.rst @@ -1045,6 +1045,7 @@ Deprecations - The ``keep_tz=False`` option (the default) of the ``keep_tz`` keyword of :meth:`DatetimeIndex.to_series` is deprecated (:issue:`17832`). - Timezone converting a tz-aware ``datetime.datetime`` or :class:`Timestamp` with :class:`Timestamp` and the ``tz`` argument is now deprecated. Instead, use :meth:`Timestamp.tz_convert` (:issue:`23579`) +- :func:`pandas.dtypes.is_period` is deprecated in favor of `pandas.dtypes.is_period_dtype` (:issue:`????`) .. _whatsnew_0240.deprecations.datetimelike_int_ops: diff --git a/pandas/core/dtypes/common.py b/pandas/core/dtypes/common.py index 5af37abd303a0..db613cb2b21f9 100644 --- a/pandas/core/dtypes/common.py +++ b/pandas/core/dtypes/common.py @@ -1,4 +1,6 @@ """ common type operations """ +import warnings + import numpy as np from pandas._libs import algos, lib @@ -363,6 +365,8 @@ def is_period(arr): """ Check whether an array-like is a periodical index. + .. deprecated:: 0.24.0 + Parameters ---------- arr : array-like @@ -382,6 +386,11 @@ def is_period(arr): True """ + warnings.warn(FutureWarning, + "'is_period' is deprecated and will be removed in a future " + "version. Use 'is_period_dtype' or is_period_arraylike' " + "instead.") + # TODO: do we need this function? # It seems like a repeat of is_period_arraylike. return isinstance(arr, ABCPeriodIndex) or is_period_arraylike(arr) diff --git a/pandas/tests/dtypes/test_common.py b/pandas/tests/dtypes/test_common.py index 4dd55321dc71f..960b9c5bd178f 100644 --- a/pandas/tests/dtypes/test_common.py +++ b/pandas/tests/dtypes/test_common.py @@ -10,6 +10,7 @@ import pandas.core.dtypes.common as com import pandas.util._test_decorators as td +import pandas.util.testing as tm class TestPandasDtype(object): @@ -172,9 +173,10 @@ def test_is_datetimetz(): def test_is_period(): - assert not com.is_period([1, 2, 3]) - assert not com.is_period(pd.Index([1, 2, 3])) - assert com.is_period(pd.PeriodIndex(["2017-01-01"], freq="D")) + with tm.assert_produces_warning(FutureWarning): + assert not com.is_period([1, 2, 3]) + assert not com.is_period(pd.Index([1, 2, 3])) + assert com.is_period(pd.PeriodIndex(["2017-01-01"], freq="D")) def test_is_datetime64_dtype(): diff --git a/pandas/tests/dtypes/test_dtypes.py b/pandas/tests/dtypes/test_dtypes.py index c70a549234a44..fd3469f7c6424 100644 --- a/pandas/tests/dtypes/test_dtypes.py +++ b/pandas/tests/dtypes/test_dtypes.py @@ -378,18 +378,22 @@ def test_basic(self): assert is_period_dtype(pidx.dtype) assert is_period_dtype(pidx) - assert is_period(pidx) + with tm.assert_produces_warning(FutureWarning): + assert is_period(pidx) s = Series(pidx, name='A') assert is_period_dtype(s.dtype) assert is_period_dtype(s) - assert is_period(s) + with tm.assert_produces_warning(FutureWarning): + assert is_period(s) assert not is_period_dtype(np.dtype('float64')) assert not is_period_dtype(1.0) - assert not is_period(np.dtype('float64')) - assert not is_period(1.0) + with tm.assert_produces_warning(FutureWarning): + assert not is_period(np.dtype('float64')) + with tm.assert_produces_warning(FutureWarning): + assert not is_period(1.0) def test_empty(self): dt = PeriodDtype() From a98375505be0fb482075c7d05e470e982517a02d Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Sun, 25 Nov 2018 15:45:45 -0800 Subject: [PATCH 05/18] deprecate is_datetimetz --- doc/source/whatsnew/v0.24.0.rst | 3 ++- pandas/core/algorithms.py | 4 ++-- pandas/core/dtypes/cast.py | 16 ++++++++-------- pandas/core/dtypes/common.py | 16 ++++++++-------- pandas/core/dtypes/concat.py | 4 ++-- pandas/core/frame.py | 5 +++-- pandas/core/indexes/datetimes.py | 4 ++-- pandas/core/internals/blocks.py | 10 +++++----- pandas/core/internals/concat.py | 9 +++++---- pandas/io/formats/format.py | 4 ++-- pandas/tests/api/test_types.py | 6 +++--- pandas/tests/dtypes/test_common.py | 13 +++++++------ pandas/tests/dtypes/test_dtypes.py | 17 +++++++++++------ pandas/tests/test_base.py | 12 ++++++------ 14 files changed, 66 insertions(+), 57 deletions(-) diff --git a/doc/source/whatsnew/v0.24.0.rst b/doc/source/whatsnew/v0.24.0.rst index e77482a826419..58f248cce2e15 100644 --- a/doc/source/whatsnew/v0.24.0.rst +++ b/doc/source/whatsnew/v0.24.0.rst @@ -1045,7 +1045,8 @@ Deprecations - The ``keep_tz=False`` option (the default) of the ``keep_tz`` keyword of :meth:`DatetimeIndex.to_series` is deprecated (:issue:`17832`). - Timezone converting a tz-aware ``datetime.datetime`` or :class:`Timestamp` with :class:`Timestamp` and the ``tz`` argument is now deprecated. Instead, use :meth:`Timestamp.tz_convert` (:issue:`23579`) -- :func:`pandas.dtypes.is_period` is deprecated in favor of `pandas.dtypes.is_period_dtype` (:issue:`????`) +- :func:`pandas.types.is_period` is deprecated in favor of `pandas.types.is_period_dtype` (:issue:`????`) +- :func:`pandas.types.is_datetimetz` is deprecated in favor of `pandas.types.is_datetime64tz` (:issue:`????`) .. _whatsnew_0240.deprecations.datetimelike_int_ops: diff --git a/pandas/core/algorithms.py b/pandas/core/algorithms.py index 5f7995ac649a2..7aceef8634e20 100644 --- a/pandas/core/algorithms.py +++ b/pandas/core/algorithms.py @@ -19,7 +19,7 @@ ensure_float64, ensure_int64, ensure_object, ensure_platform_int, ensure_uint64, is_array_like, is_bool_dtype, is_categorical_dtype, is_complex_dtype, is_datetime64_any_dtype, is_datetime64tz_dtype, - is_datetimelike, is_datetimetz, is_extension_array_dtype, is_float_dtype, + is_datetimelike, is_extension_array_dtype, is_float_dtype, is_integer_dtype, is_interval_dtype, is_list_like, is_numeric_dtype, is_object_dtype, is_period_dtype, is_scalar, is_signed_integer_dtype, is_sparse, is_timedelta64_dtype, is_unsigned_integer_dtype, @@ -1581,7 +1581,7 @@ def take_nd(arr, indexer, axis=0, out=None, fill_value=np.nan, mask_info=None, # dispatch to internal type takes if is_extension_array_dtype(arr): return arr.take(indexer, fill_value=fill_value, allow_fill=allow_fill) - elif is_datetimetz(arr): + elif is_datetime64tz_dtype(arr): return arr.take(indexer, fill_value=fill_value, allow_fill=allow_fill) elif is_interval_dtype(arr): return arr.take(indexer, fill_value=fill_value, allow_fill=allow_fill) diff --git a/pandas/core/dtypes/cast.py b/pandas/core/dtypes/cast.py index 791b3b6421e2b..09026ffbc6cd7 100644 --- a/pandas/core/dtypes/cast.py +++ b/pandas/core/dtypes/cast.py @@ -13,11 +13,11 @@ ensure_int8, ensure_int16, ensure_int32, ensure_int64, ensure_object, is_bool, is_bool_dtype, is_categorical_dtype, is_complex, is_complex_dtype, is_datetime64_dtype, is_datetime64_ns_dtype, is_datetime64tz_dtype, - is_datetime_or_timedelta_dtype, is_datetimelike, is_datetimetz, - is_dtype_equal, is_extension_array_dtype, is_extension_type, is_float, - is_float_dtype, is_integer, is_integer_dtype, is_object_dtype, is_scalar, - is_string_dtype, is_timedelta64_dtype, is_timedelta64_ns_dtype, - is_unsigned_integer_dtype, pandas_dtype) + is_datetime_or_timedelta_dtype, is_datetimelike, is_dtype_equal, + is_extension_array_dtype, is_extension_type, is_float, is_float_dtype, + is_integer, is_integer_dtype, is_object_dtype, is_scalar, is_string_dtype, + is_timedelta64_dtype, is_timedelta64_ns_dtype, is_unsigned_integer_dtype, + pandas_dtype) from .dtypes import ( DatetimeTZDtype, ExtensionDtype, PandasExtensionDtype, PeriodDtype) from .generic import ABCDatetimeIndex, ABCPeriodIndex, ABCSeries @@ -285,7 +285,7 @@ def maybe_promote(dtype, fill_value=np.nan): fill_value = iNaT else: fill_value = iNaT - elif is_datetimetz(dtype): + elif is_datetime64tz_dtype(dtype): if isna(fill_value): fill_value = iNaT elif is_extension_array_dtype(dtype) and isna(fill_value): @@ -328,7 +328,7 @@ def maybe_promote(dtype, fill_value=np.nan): # in case we have a string that looked like a number if is_extension_array_dtype(dtype): pass - elif is_datetimetz(dtype): + elif is_datetime64tz_dtype(dtype): pass elif issubclass(np.dtype(dtype).type, string_types): dtype = np.object_ @@ -1178,7 +1178,7 @@ def construct_1d_arraylike_from_scalar(value, length, dtype): np.ndarray / pandas type of length, filled with value """ - if is_datetimetz(dtype): + if is_datetime64tz_dtype(dtype): from pandas import DatetimeIndex subarr = DatetimeIndex([value] * length, dtype=dtype) elif is_categorical_dtype(dtype): diff --git a/pandas/core/dtypes/common.py b/pandas/core/dtypes/common.py index db613cb2b21f9..e3a8b2fb80957 100644 --- a/pandas/core/dtypes/common.py +++ b/pandas/core/dtypes/common.py @@ -289,6 +289,8 @@ def is_datetimetz(arr): Check whether an array-like is a datetime array-like with a timezone component in its dtype. + .. deprecated:: 0.24.0 + Parameters ---------- arr : array-like @@ -322,8 +324,9 @@ def is_datetimetz(arr): True """ - # TODO: do we need this function? - # It seems like a repeat of is_datetime64tz_dtype. + warnings.warn(FutureWarning, + "'is_datetimetz' is deprecated and will be removed in a " + "future version. Use 'is_datetime64tz_dtype' instead.") return ((isinstance(arr, ABCDatetimeIndex) and getattr(arr, 'tz', None) is not None) or @@ -391,8 +394,6 @@ def is_period(arr): "version. Use 'is_period_dtype' or is_period_arraylike' " "instead.") - # TODO: do we need this function? - # It seems like a repeat of is_period_arraylike. return isinstance(arr, ABCPeriodIndex) or is_period_arraylike(arr) @@ -752,8 +753,7 @@ def is_datetimelike(arr): return (is_datetime64_dtype(arr) or is_datetime64tz_dtype(arr) or is_timedelta64_dtype(arr) or - isinstance(arr, ABCPeriodIndex) or - is_datetimetz(arr)) + isinstance(arr, ABCPeriodIndex)) def is_dtype_equal(source, target): @@ -1751,7 +1751,7 @@ def is_extension_type(arr): return True elif is_sparse(arr): return True - elif is_datetimetz(arr): + elif is_datetime64tz_dtype(arr): return True return False @@ -1984,7 +1984,7 @@ def _get_dtype_from_object(dtype): return dtype elif is_categorical(dtype): return CategoricalDtype().type - elif is_datetimetz(dtype): + elif is_datetime64tz_dtype(dtype): return DatetimeTZDtype(dtype).type elif isinstance(dtype, np.dtype): # dtype object try: diff --git a/pandas/core/dtypes/concat.py b/pandas/core/dtypes/concat.py index f482f7e1927b7..098ac3e0c00a5 100644 --- a/pandas/core/dtypes/concat.py +++ b/pandas/core/dtypes/concat.py @@ -8,7 +8,7 @@ from pandas.core.dtypes.common import ( _NS_DTYPE, _TD_DTYPE, is_bool_dtype, is_categorical_dtype, - is_datetime64_dtype, is_datetimetz, is_dtype_equal, + is_datetime64_dtype, is_datetime64tz_dtype, is_dtype_equal, is_extension_array_dtype, is_interval_dtype, is_object_dtype, is_period_dtype, is_sparse, is_timedelta64_dtype) from pandas.core.dtypes.generic import ( @@ -39,7 +39,7 @@ def get_dtype_kinds(l): typ = 'sparse' elif isinstance(arr, ABCRangeIndex): typ = 'range' - elif is_datetimetz(arr): + elif is_datetime64tz_dtype(arr): # if to_concat contains different tz, # the result must be object dtype typ = str(arr.dtype) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 032d68e2d3e8c..0d9af3e0bc6ed 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -54,7 +54,7 @@ is_object_dtype, is_extension_type, is_extension_array_dtype, - is_datetimetz, + is_datetime64tz_dtype, is_datetime64_any_dtype, is_bool_dtype, is_integer_dtype, @@ -541,7 +541,8 @@ def _get_axes(N, K, index=index, columns=columns): index, columns = _get_axes(len(values), 1) return _arrays_to_mgr([values], columns, index, columns, dtype=dtype) - elif (is_datetimetz(values) or is_extension_array_dtype(values)): + elif (is_datetime64tz_dtype(values) or + is_extension_array_dtype(values)): # GH19157 if columns is None: columns = [0] diff --git a/pandas/core/indexes/datetimes.py b/pandas/core/indexes/datetimes.py index 6b66170e978ed..33b027e8547fd 100644 --- a/pandas/core/indexes/datetimes.py +++ b/pandas/core/indexes/datetimes.py @@ -16,7 +16,7 @@ from pandas.core.dtypes.common import ( _INT64_DTYPE, _NS_DTYPE, ensure_int64, is_datetime64_dtype, - is_datetime64_ns_dtype, is_datetimetz, is_dtype_equal, is_float, + is_datetime64_ns_dtype, is_datetime64tz_dtype, is_dtype_equal, is_float, is_integer, is_integer_dtype, is_list_like, is_period_dtype, is_scalar, is_string_like, pandas_dtype) import pandas.core.dtypes.concat as _concat @@ -259,7 +259,7 @@ def __new__(cls, data=None, data = data._values # data must be Index or np.ndarray here - if not (is_datetime64_dtype(data) or is_datetimetz(data) or + if not (is_datetime64_dtype(data) or is_datetime64tz_dtype(data) or is_integer_dtype(data) or lib.infer_dtype(data) == 'integer'): data = tools.to_datetime(data, dayfirst=dayfirst, yearfirst=yearfirst) diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index 857bf18c5982b..6f9cd31a826a4 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -20,7 +20,7 @@ from pandas.core.dtypes.common import ( _NS_DTYPE, _TD_DTYPE, ensure_platform_int, is_bool_dtype, is_categorical, is_categorical_dtype, is_datetime64_dtype, is_datetime64tz_dtype, - is_datetimetz, is_dtype_equal, is_extension_array_dtype, is_extension_type, + is_dtype_equal, is_extension_array_dtype, is_extension_type, is_float_dtype, is_integer, is_integer_dtype, is_list_like, is_numeric_v_string_like, is_object_dtype, is_re, is_re_compilable, is_sparse, is_timedelta64_dtype, pandas_dtype) @@ -2770,7 +2770,7 @@ def to_native_types(self, slicer=None, na_rep=None, date_format=None, def should_store(self, value): return (issubclass(value.dtype.type, np.datetime64) and - not is_datetimetz(value) and + not is_datetime64tz_dtype(value) and not is_extension_array_dtype(value)) def set(self, locs, values, check=False): @@ -3024,9 +3024,9 @@ def get_block_type(values, dtype=None): elif issubclass(vtype, np.complexfloating): cls = ComplexBlock elif issubclass(vtype, np.datetime64): - assert not is_datetimetz(values) + assert not is_datetime64tz_dtype(values) cls = DatetimeBlock - elif is_datetimetz(values): + elif is_datetime64tz_dtype(values): cls = DatetimeTZBlock elif issubclass(vtype, np.integer): cls = IntBlock @@ -3047,7 +3047,7 @@ def make_block(values, placement, klass=None, ndim=None, dtype=None, dtype = dtype or values.dtype klass = get_block_type(values, dtype) - elif klass is DatetimeTZBlock and not is_datetimetz(values): + elif klass is DatetimeTZBlock and not is_datetime64tz_dtype(values): return klass(values, ndim=ndim, placement=placement, dtype=dtype) diff --git a/pandas/core/internals/concat.py b/pandas/core/internals/concat.py index 2fb533478b2f3..2441c64518d59 100644 --- a/pandas/core/internals/concat.py +++ b/pandas/core/internals/concat.py @@ -10,8 +10,9 @@ from pandas.core.dtypes.cast import maybe_promote from pandas.core.dtypes.common import ( - _get_dtype, is_categorical_dtype, is_datetime64_dtype, is_datetimetz, - is_float_dtype, is_numeric_dtype, is_sparse, is_timedelta64_dtype) + _get_dtype, is_categorical_dtype, is_datetime64_dtype, + is_datetime64tz_dtype, is_float_dtype, is_numeric_dtype, is_sparse, + is_timedelta64_dtype) import pandas.core.dtypes.concat as _concat from pandas.core.dtypes.missing import isna @@ -179,7 +180,7 @@ def get_reindexed_values(self, empty_dtype, upcasted_na): fill_value = None if (getattr(self.block, 'is_datetimetz', False) or - is_datetimetz(empty_dtype)): + is_datetime64tz_dtype(empty_dtype)): if self.block is None: array = empty_dtype.construct_array_type() missing_arr = array([fill_value], dtype=empty_dtype) @@ -293,7 +294,7 @@ def get_empty_dtype_and_na(join_units): if is_categorical_dtype(dtype): upcast_cls = 'category' - elif is_datetimetz(dtype): + elif is_datetime64tz_dtype(dtype): upcast_cls = 'datetimetz' elif issubclass(dtype.type, np.bool_): upcast_cls = 'bool' diff --git a/pandas/io/formats/format.py b/pandas/io/formats/format.py index c777b89eeaf12..de5efad6c7910 100644 --- a/pandas/io/formats/format.py +++ b/pandas/io/formats/format.py @@ -16,7 +16,7 @@ from pandas.compat import StringIO, lzip, map, u, zip from pandas.core.dtypes.common import ( - is_categorical_dtype, is_datetime64_dtype, is_datetimetz, is_float, + is_categorical_dtype, is_datetime64_dtype, is_datetime64tz_dtype, is_float, is_float_dtype, is_integer, is_integer_dtype, is_interval_dtype, is_list_like, is_numeric_dtype, is_period_arraylike, is_scalar, is_timedelta64_dtype) @@ -856,7 +856,7 @@ def format_array(values, formatter, float_format=None, na_rep='NaN', fmt_klass = PeriodArrayFormatter elif is_integer_dtype(values.dtype): fmt_klass = IntArrayFormatter - elif is_datetimetz(values): + elif is_datetime64tz_dtype(values): fmt_klass = Datetime64TZFormatter elif is_datetime64_dtype(values.dtype): fmt_klass = Datetime64Formatter diff --git a/pandas/tests/api/test_types.py b/pandas/tests/api/test_types.py index c36af4404e646..3468a4db617b0 100644 --- a/pandas/tests/api/test_types.py +++ b/pandas/tests/api/test_types.py @@ -13,21 +13,21 @@ class TestTypes(Base): 'is_categorical', 'is_categorical_dtype', 'is_complex', 'is_complex_dtype', 'is_datetime64_any_dtype', 'is_datetime64_dtype', 'is_datetime64_ns_dtype', - 'is_datetime64tz_dtype', 'is_datetimetz', 'is_dtype_equal', + 'is_datetime64tz_dtype', 'is_dtype_equal', 'is_extension_type', 'is_float', 'is_float_dtype', 'is_int64_dtype', 'is_integer', 'is_integer_dtype', 'is_number', 'is_numeric_dtype', 'is_object_dtype', 'is_scalar', 'is_sparse', 'is_string_dtype', 'is_signed_integer_dtype', 'is_timedelta64_dtype', 'is_timedelta64_ns_dtype', - 'is_unsigned_integer_dtype', 'is_period', + 'is_unsigned_integer_dtype', 'is_period_dtype', 'is_interval', 'is_interval_dtype', 'is_re', 'is_re_compilable', 'is_dict_like', 'is_iterator', 'is_file_like', 'is_list_like', 'is_hashable', 'is_array_like', 'is_named_tuple', 'pandas_dtype', 'union_categoricals', 'infer_dtype'] - deprecated = [] + deprecated = ['is_period', 'is_datetimetz'] dtypes = ['CategoricalDtype', 'DatetimeTZDtype', 'PeriodDtype', 'IntervalDtype'] diff --git a/pandas/tests/dtypes/test_common.py b/pandas/tests/dtypes/test_common.py index 960b9c5bd178f..73a31b41cb01e 100644 --- a/pandas/tests/dtypes/test_common.py +++ b/pandas/tests/dtypes/test_common.py @@ -162,14 +162,15 @@ def test_is_categorical(): def test_is_datetimetz(): - assert not com.is_datetimetz([1, 2, 3]) - assert not com.is_datetimetz(pd.DatetimeIndex([1, 2, 3])) + with tm.assert_produces_warning(FutureWarning): + assert not com.is_datetimetz([1, 2, 3]) + assert not com.is_datetimetz(pd.DatetimeIndex([1, 2, 3])) - assert com.is_datetimetz(pd.DatetimeIndex([1, 2, 3], tz="US/Eastern")) + assert com.is_datetimetz(pd.DatetimeIndex([1, 2, 3], tz="US/Eastern")) - dtype = DatetimeTZDtype("ns", tz="US/Eastern") - s = pd.Series([], dtype=dtype) - assert com.is_datetimetz(s) + dtype = DatetimeTZDtype("ns", tz="US/Eastern") + s = pd.Series([], dtype=dtype) + assert com.is_datetimetz(s) def test_is_period(): diff --git a/pandas/tests/dtypes/test_dtypes.py b/pandas/tests/dtypes/test_dtypes.py index fd3469f7c6424..4048e98142a7f 100644 --- a/pandas/tests/dtypes/test_dtypes.py +++ b/pandas/tests/dtypes/test_dtypes.py @@ -229,20 +229,25 @@ def test_basic(self): assert not is_datetime64tz_dtype(np.dtype('float64')) assert not is_datetime64tz_dtype(1.0) - assert is_datetimetz(s) - assert is_datetimetz(s.dtype) - assert not is_datetimetz(np.dtype('float64')) - assert not is_datetimetz(1.0) + with tm.assert_produces_warning(FutureWarning): + assert is_datetimetz(s) + assert is_datetimetz(s.dtype) + assert not is_datetimetz(np.dtype('float64')) + assert not is_datetimetz(1.0) def test_dst(self): dr1 = date_range('2013-01-01', periods=3, tz='US/Eastern') s1 = Series(dr1, name='A') - assert is_datetimetz(s1) + assert is_datetime64tz_dtype(s1) + with tm.assert_produces_warning(FutureWarning): + assert is_datetimetz(s1) dr2 = date_range('2013-08-01', periods=3, tz='US/Eastern') s2 = Series(dr2, name='A') - assert is_datetimetz(s2) + assert is_datetime64tz_dtype(s2) + with tm.assert_produces_warning(FutureWarning): + assert is_datetimetz(s2) assert s1.dtype == s2.dtype @pytest.mark.parametrize('tz', ['UTC', 'US/Eastern']) diff --git a/pandas/tests/test_base.py b/pandas/tests/test_base.py index 084477d8202b1..a4f72f044a620 100644 --- a/pandas/tests/test_base.py +++ b/pandas/tests/test_base.py @@ -10,7 +10,7 @@ import pandas as pd import pandas.compat as compat from pandas.core.dtypes.common import ( - is_object_dtype, is_datetimetz, is_datetime64_dtype, + is_object_dtype, is_datetime64_dtype, is_datetime64tz_dtype, needs_i8_conversion) import pandas.util.testing as tm from pandas import (Series, Index, DatetimeIndex, TimedeltaIndex, @@ -297,7 +297,7 @@ def test_none_comparison(self): # result = None != o # noqa # assert result.iat[0] # assert result.iat[1] - if (is_datetime64_dtype(o) or is_datetimetz(o)): + if (is_datetime64_dtype(o) or is_datetime64tz_dtype(o)): # Following DatetimeIndex (and Timestamp) convention, # inequality comparisons with Series[datetime64] raise with pytest.raises(TypeError): @@ -447,7 +447,7 @@ def test_value_counts_unique_nunique(self): if isinstance(o, Index): assert isinstance(result, o.__class__) tm.assert_index_equal(result, orig) - elif is_datetimetz(o): + elif is_datetime64tz_dtype(o): # datetimetz Series returns array of Timestamp assert result[0] == orig[0] for r in result: @@ -471,7 +471,7 @@ def test_value_counts_unique_nunique_null(self): continue # special assign to the numpy array - if is_datetimetz(o): + if is_datetime64tz_dtype(o): if isinstance(o, DatetimeIndex): v = o.asi8 v[0:2] = iNaT @@ -500,7 +500,7 @@ def test_value_counts_unique_nunique_null(self): o = klass(values.repeat(range(1, len(o) + 1))) o.name = 'a' else: - if is_datetimetz(o): + if is_datetime64tz_dtype(o): expected_index = orig._values._shallow_copy(values) else: expected_index = Index(values) @@ -539,7 +539,7 @@ def test_value_counts_unique_nunique_null(self): if isinstance(o, Index): tm.assert_index_equal(result, Index(values[1:], name='a')) - elif is_datetimetz(o): + elif is_datetime64tz_dtype(o): # unable to compare NaT / nan vals = values[2:].astype(object).values tm.assert_numpy_array_equal(result[1:], vals) From d7944b6f746d476d4c2b71e716d0cb5ffeea7aa8 Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Sun, 25 Nov 2018 17:12:08 -0800 Subject: [PATCH 06/18] set stacklevel --- pandas/core/dtypes/common.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/pandas/core/dtypes/common.py b/pandas/core/dtypes/common.py index e3a8b2fb80957..efd29d35293ab 100644 --- a/pandas/core/dtypes/common.py +++ b/pandas/core/dtypes/common.py @@ -324,9 +324,9 @@ def is_datetimetz(arr): True """ - warnings.warn(FutureWarning, - "'is_datetimetz' is deprecated and will be removed in a " - "future version. Use 'is_datetime64tz_dtype' instead.") + warnings.warn("'is_datetimetz' is deprecated and will be removed in a " + "future version. Use 'is_datetime64tz_dtype' instead.", + FutureWarning, stacklevel=2) return ((isinstance(arr, ABCDatetimeIndex) and getattr(arr, 'tz', None) is not None) or @@ -389,10 +389,9 @@ def is_period(arr): True """ - warnings.warn(FutureWarning, - "'is_period' is deprecated and will be removed in a future " + warnings.warn("'is_period' is deprecated and will be removed in a future " "version. Use 'is_period_dtype' or is_period_arraylike' " - "instead.") + "instead.", FutureWarning, stacklevel=2) return isinstance(arr, ABCPeriodIndex) or is_period_arraylike(arr) From 34c4e91c6d45f218d5ece4b2a1b49a07df2d7e7c Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Sun, 25 Nov 2018 18:59:52 -0800 Subject: [PATCH 07/18] remove unused is_timedelta_array and is_timedelta64_array --- pandas/_libs/lib.pyx | 31 ++------------------------- pandas/tests/dtypes/test_inference.py | 12 ----------- 2 files changed, 2 insertions(+), 41 deletions(-) diff --git a/pandas/_libs/lib.pyx b/pandas/_libs/lib.pyx index ad538ff103c2f..adaf7f0a6a9c5 100644 --- a/pandas/_libs/lib.pyx +++ b/pandas/_libs/lib.pyx @@ -1250,25 +1250,19 @@ def infer_dtype(value: object, skipna: bool=False) -> str: if util.is_datetime64_object(val): if is_datetime64_array(values): return 'datetime64' - elif is_timedelta_or_timedelta64_array(values): - return 'timedelta' elif is_timedelta(val): if is_timedelta_or_timedelta64_array(values): return 'timedelta' elif util.is_integer_object(val): - # a timedelta will show true here as well - if is_timedelta(val): - if is_timedelta_or_timedelta64_array(values): - return 'timedelta' + # numpy timedelta64 objects are caught in the previous branch; + # ordering matters here if is_integer_array(values): return 'integer' elif is_integer_float_array(values): return 'mixed-integer-float' - elif is_timedelta_or_timedelta64_array(values): - return 'timedelta' return 'mixed-integer' elif PyDateTime_Check(val): @@ -1701,27 +1695,6 @@ cdef class TimedeltaValidator(TemporalValidator): return is_null_timedelta64(value) -# TODO: Not used outside of tests; remove? -def is_timedelta_array(values: ndarray) -> bool: - cdef: - TimedeltaValidator validator = TimedeltaValidator(len(values), - skipna=True) - return validator.validate(values) - - -cdef class Timedelta64Validator(TimedeltaValidator): - cdef inline bint is_value_typed(self, object value) except -1: - return util.is_timedelta64_object(value) - - -# TODO: Not used outside of tests; remove? -def is_timedelta64_array(values: ndarray) -> bool: - cdef: - Timedelta64Validator validator = Timedelta64Validator(len(values), - skipna=True) - return validator.validate(values) - - cdef class AnyTimedeltaValidator(TimedeltaValidator): cdef inline bint is_value_typed(self, object value) except -1: return is_timedelta(value) diff --git a/pandas/tests/dtypes/test_inference.py b/pandas/tests/dtypes/test_inference.py index fd3222cd1119b..50ee300201511 100644 --- a/pandas/tests/dtypes/test_inference.py +++ b/pandas/tests/dtypes/test_inference.py @@ -875,37 +875,27 @@ def test_is_datetimelike_array_all_nan_nat_like(self): arr = np.array([np.nan, pd.NaT, np.datetime64('nat')]) assert lib.is_datetime_array(arr) assert lib.is_datetime64_array(arr) - assert not lib.is_timedelta_array(arr) - assert not lib.is_timedelta64_array(arr) assert not lib.is_timedelta_or_timedelta64_array(arr) arr = np.array([np.nan, pd.NaT, np.timedelta64('nat')]) assert not lib.is_datetime_array(arr) assert not lib.is_datetime64_array(arr) - assert lib.is_timedelta_array(arr) - assert lib.is_timedelta64_array(arr) assert lib.is_timedelta_or_timedelta64_array(arr) arr = np.array([np.nan, pd.NaT, np.datetime64('nat'), np.timedelta64('nat')]) assert not lib.is_datetime_array(arr) assert not lib.is_datetime64_array(arr) - assert not lib.is_timedelta_array(arr) - assert not lib.is_timedelta64_array(arr) assert not lib.is_timedelta_or_timedelta64_array(arr) arr = np.array([np.nan, pd.NaT]) assert lib.is_datetime_array(arr) assert lib.is_datetime64_array(arr) - assert lib.is_timedelta_array(arr) - assert lib.is_timedelta64_array(arr) assert lib.is_timedelta_or_timedelta64_array(arr) arr = np.array([np.nan, np.nan], dtype=object) assert not lib.is_datetime_array(arr) assert not lib.is_datetime64_array(arr) - assert not lib.is_timedelta_array(arr) - assert not lib.is_timedelta64_array(arr) assert not lib.is_timedelta_or_timedelta64_array(arr) assert lib.is_datetime_with_singletz_array( @@ -923,8 +913,6 @@ def test_is_datetimelike_array_all_nan_nat_like(self): 'is_datetime_array', 'is_datetime64_array', 'is_bool_array', - 'is_timedelta_array', - 'is_timedelta64_array', 'is_timedelta_or_timedelta64_array', 'is_date_array', 'is_time_array', From 8e86599f33fb70891e0f12fa3f5a10c87a0452cb Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Sun, 25 Nov 2018 19:06:28 -0800 Subject: [PATCH 08/18] remove is_int_or_datetime_dtype --- pandas/core/dtypes/common.py | 48 ------------------------------ pandas/core/nanops.py | 5 ++-- pandas/core/reshape/merge.py | 5 ++-- pandas/tests/dtypes/test_common.py | 15 ---------- 4 files changed, 6 insertions(+), 67 deletions(-) diff --git a/pandas/core/dtypes/common.py b/pandas/core/dtypes/common.py index efd29d35293ab..68a07912424f5 100644 --- a/pandas/core/dtypes/common.py +++ b/pandas/core/dtypes/common.py @@ -1058,54 +1058,6 @@ def is_int64_dtype(arr_or_dtype): return issubclass(tipo, np.int64) -def is_int_or_datetime_dtype(arr_or_dtype): - """ - Check whether the provided array or dtype is of an - integer, timedelta64, or datetime64 dtype. - - Parameters - ---------- - arr_or_dtype : array-like - The array or dtype to check. - - Returns - ------- - boolean : Whether or not the array or dtype is of an - integer, timedelta64, or datetime64 dtype. - - Examples - -------- - >>> is_int_or_datetime_dtype(str) - False - >>> is_int_or_datetime_dtype(int) - True - >>> is_int_or_datetime_dtype(float) - False - >>> is_int_or_datetime_dtype(np.uint64) - True - >>> is_int_or_datetime_dtype(np.datetime64) - True - >>> is_int_or_datetime_dtype(np.timedelta64) - True - >>> is_int_or_datetime_dtype(np.array(['a', 'b'])) - False - >>> is_int_or_datetime_dtype(pd.Series([1, 2])) - True - >>> is_int_or_datetime_dtype(np.array([], dtype=np.timedelta64)) - True - >>> is_int_or_datetime_dtype(np.array([], dtype=np.datetime64)) - True - >>> is_int_or_datetime_dtype(pd.Index([1, 2.])) # float - False - """ - - if arr_or_dtype is None: - return False - tipo = _get_dtype_type(arr_or_dtype) - return (issubclass(tipo, np.integer) or - issubclass(tipo, (np.datetime64, np.timedelta64))) - - def is_datetime64_any_dtype(arr_or_dtype): """ Check whether the provided array or dtype is of the datetime64 dtype. diff --git a/pandas/core/nanops.py b/pandas/core/nanops.py index 4369ac60a075e..03b24242908a9 100644 --- a/pandas/core/nanops.py +++ b/pandas/core/nanops.py @@ -13,7 +13,7 @@ from pandas.core.dtypes.common import ( _get_dtype, is_any_int_dtype, is_bool_dtype, is_complex, is_complex_dtype, is_datetime64_dtype, is_datetime_or_timedelta_dtype, is_float, - is_float_dtype, is_int_or_datetime_dtype, is_integer, is_integer_dtype, + is_float_dtype, is_integer, is_integer_dtype, is_numeric_dtype, is_object_dtype, is_scalar, is_timedelta64_dtype) from pandas.core.dtypes.missing import isna, na_value_for_dtype, notna @@ -254,7 +254,8 @@ def _isfinite(values): def _na_ok_dtype(dtype): - return not is_int_or_datetime_dtype(dtype) + # TODO: what about datetime64tz? PeriodDtype? + return not issubclass(dtype, (np.integer, np.timedelta64, np.datetime64)) def _view_if_needed(values): diff --git a/pandas/core/reshape/merge.py b/pandas/core/reshape/merge.py index a7e83c88cd355..4012efe9e075e 100644 --- a/pandas/core/reshape/merge.py +++ b/pandas/core/reshape/merge.py @@ -18,7 +18,7 @@ ensure_float64, ensure_int64, ensure_object, is_array_like, is_bool, is_bool_dtype, is_categorical_dtype, is_datetime64_dtype, is_datetime64tz_dtype, is_datetimelike, is_dtype_equal, is_float_dtype, - is_int64_dtype, is_int_or_datetime_dtype, is_integer, is_integer_dtype, + is_int64_dtype, is_integer, is_integer_dtype, is_list_like, is_number, is_numeric_dtype, needs_i8_conversion) from pandas.core.dtypes.missing import isnull, na_value_for_dtype @@ -1604,7 +1604,8 @@ def _factorize_keys(lk, rk, sort=True): lk = ensure_int64(lk.codes) rk = ensure_int64(rk) - elif is_int_or_datetime_dtype(lk) and is_int_or_datetime_dtype(rk): + elif (issubclass(lk.dtype, (np.integer, np.timedelta64, np.datetime64)) and + issubclass(rk.dtype, (np.integer, np.timedelta64, np.datetime64))): klass = libhashtable.Int64Factorizer lk = ensure_int64(com.values_from_object(lk)) rk = ensure_int64(com.values_from_object(rk)) diff --git a/pandas/tests/dtypes/test_common.py b/pandas/tests/dtypes/test_common.py index 73a31b41cb01e..93230bccf6929 100644 --- a/pandas/tests/dtypes/test_common.py +++ b/pandas/tests/dtypes/test_common.py @@ -331,21 +331,6 @@ def test_is_int64_dtype(): assert com.is_int64_dtype(np.array([1, 2], dtype=np.int64)) -def test_is_int_or_datetime_dtype(): - assert not com.is_int_or_datetime_dtype(str) - assert not com.is_int_or_datetime_dtype(float) - assert not com.is_int_or_datetime_dtype(pd.Index([1, 2.])) - assert not com.is_int_or_datetime_dtype(np.array(['a', 'b'])) - - assert com.is_int_or_datetime_dtype(int) - assert com.is_int_or_datetime_dtype(np.uint64) - assert com.is_int_or_datetime_dtype(np.datetime64) - assert com.is_int_or_datetime_dtype(np.timedelta64) - assert com.is_int_or_datetime_dtype(pd.Series([1, 2])) - assert com.is_int_or_datetime_dtype(np.array([], dtype=np.datetime64)) - assert com.is_int_or_datetime_dtype(np.array([], dtype=np.timedelta64)) - - def test_is_datetime64_any_dtype(): assert not com.is_datetime64_any_dtype(int) assert not com.is_datetime64_any_dtype(str) From 0cf62393c332c2b6e9eac96e62a4cd306d286b01 Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Sun, 25 Nov 2018 19:11:46 -0800 Subject: [PATCH 09/18] GH reference --- doc/source/whatsnew/v0.24.0.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/source/whatsnew/v0.24.0.rst b/doc/source/whatsnew/v0.24.0.rst index 57b3b8798921a..a0e2cd8d84756 100644 --- a/doc/source/whatsnew/v0.24.0.rst +++ b/doc/source/whatsnew/v0.24.0.rst @@ -1046,8 +1046,8 @@ Deprecations - The ``keep_tz=False`` option (the default) of the ``keep_tz`` keyword of :meth:`DatetimeIndex.to_series` is deprecated (:issue:`17832`). - Timezone converting a tz-aware ``datetime.datetime`` or :class:`Timestamp` with :class:`Timestamp` and the ``tz`` argument is now deprecated. Instead, use :meth:`Timestamp.tz_convert` (:issue:`23579`) -- :func:`pandas.types.is_period` is deprecated in favor of `pandas.types.is_period_dtype` (:issue:`????`) -- :func:`pandas.types.is_datetimetz` is deprecated in favor of `pandas.types.is_datetime64tz` (:issue:`????`) +- :func:`pandas.types.is_period` is deprecated in favor of `pandas.types.is_period_dtype` (:issue:`23917`) +- :func:`pandas.types.is_datetimetz` is deprecated in favor of `pandas.types.is_datetime64tz` (:issue:`23917`) .. _whatsnew_0240.deprecations.datetimelike_int_ops: From 8adda173228ad82007b16deee575c3a44cfe4fdf Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Sun, 25 Nov 2018 19:48:10 -0800 Subject: [PATCH 10/18] fixup typecheck --- pandas/core/nanops.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pandas/core/nanops.py b/pandas/core/nanops.py index 03b24242908a9..6356aa0e9cf24 100644 --- a/pandas/core/nanops.py +++ b/pandas/core/nanops.py @@ -255,7 +255,8 @@ def _isfinite(values): def _na_ok_dtype(dtype): # TODO: what about datetime64tz? PeriodDtype? - return not issubclass(dtype, (np.integer, np.timedelta64, np.datetime64)) + return not issubclass(dtype.type, + (np.integer, np.timedelta64, np.datetime64)) def _view_if_needed(values): From fe022402444ad2bfc11c27fb2bb9224a2764ee01 Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Mon, 26 Nov 2018 05:50:14 -0800 Subject: [PATCH 11/18] typo fixu[ --- pandas/core/reshape/merge.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pandas/core/reshape/merge.py b/pandas/core/reshape/merge.py index 4012efe9e075e..5024c18902739 100644 --- a/pandas/core/reshape/merge.py +++ b/pandas/core/reshape/merge.py @@ -1604,8 +1604,10 @@ def _factorize_keys(lk, rk, sort=True): lk = ensure_int64(lk.codes) rk = ensure_int64(rk) - elif (issubclass(lk.dtype, (np.integer, np.timedelta64, np.datetime64)) and - issubclass(rk.dtype, (np.integer, np.timedelta64, np.datetime64))): + elif (issubclass(lk.dtype.type, (np.integer, np.timedelta64, + np.datetime64)) and + issubclass(rk.dtype.type, (np.integer, np.timedelta64, + np.datetime64))): klass = libhashtable.Int64Factorizer lk = ensure_int64(com.values_from_object(lk)) rk = ensure_int64(com.values_from_object(rk)) From e2f86695948fc8b1ef77420a1c7252cafa968a6a Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Mon, 26 Nov 2018 08:53:54 -0800 Subject: [PATCH 12/18] Address comments --- doc/source/whatsnew/v0.24.0.rst | 1 - pandas/_libs/lib.pyx | 4 ++-- pandas/core/dtypes/common.py | 5 +---- pandas/tests/dtypes/test_common.py | 2 +- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/doc/source/whatsnew/v0.24.0.rst b/doc/source/whatsnew/v0.24.0.rst index 0ba9ccfd23bab..ba1d56e89042e 100644 --- a/doc/source/whatsnew/v0.24.0.rst +++ b/doc/source/whatsnew/v0.24.0.rst @@ -1127,7 +1127,6 @@ Removal of prior version deprecations/changes - :meth:`SparseSeries.to_dense` has dropped the ``sparse_only`` parameter (:issue:`14686`) - :meth:`DataFrame.astype` and :meth:`Series.astype` have renamed the ``raise_on_error`` argument to ``errors`` (:issue:`14967`) - ``is_sequence``, ``is_any_int_dtype``, and ``is_floating_dtype`` have been removed from ``pandas.api.types`` (:issue:`16163`, :issue:`16189`) -- ``is_floating_dtype`` has been removed (:issue:`????`) .. _whatsnew_0240.performance: diff --git a/pandas/_libs/lib.pyx b/pandas/_libs/lib.pyx index adaf7f0a6a9c5..18cef1fa3cf26 100644 --- a/pandas/_libs/lib.pyx +++ b/pandas/_libs/lib.pyx @@ -1256,8 +1256,8 @@ def infer_dtype(value: object, skipna: bool=False) -> str: return 'timedelta' elif util.is_integer_object(val): - # numpy timedelta64 objects are caught in the previous branch; - # ordering matters here + # ordering matters here; this check must come after the is_timedelta + # check otherwise numpy timedelta64 objects would come through here if is_integer_array(values): return 'integer' diff --git a/pandas/core/dtypes/common.py b/pandas/core/dtypes/common.py index 68a07912424f5..51b8488313e99 100644 --- a/pandas/core/dtypes/common.py +++ b/pandas/core/dtypes/common.py @@ -327,10 +327,7 @@ def is_datetimetz(arr): warnings.warn("'is_datetimetz' is deprecated and will be removed in a " "future version. Use 'is_datetime64tz_dtype' instead.", FutureWarning, stacklevel=2) - - return ((isinstance(arr, ABCDatetimeIndex) and - getattr(arr, 'tz', None) is not None) or - is_datetime64tz_dtype(arr)) + return is_datetime64tz_dtype(arr) def is_offsetlike(arr_or_obj): diff --git a/pandas/tests/dtypes/test_common.py b/pandas/tests/dtypes/test_common.py index 93230bccf6929..a7390e0cffbbf 100644 --- a/pandas/tests/dtypes/test_common.py +++ b/pandas/tests/dtypes/test_common.py @@ -173,7 +173,7 @@ def test_is_datetimetz(): assert com.is_datetimetz(s) -def test_is_period(): +def test_is_period_deprecated(): with tm.assert_produces_warning(FutureWarning): assert not com.is_period([1, 2, 3]) assert not com.is_period(pd.Index([1, 2, 3])) From 3daaabf6d3d3d2c78b0acd33f693c8bea168cd53 Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Mon, 26 Nov 2018 09:56:23 -0800 Subject: [PATCH 13/18] isort --- pandas/core/nanops.py | 4 ++-- pandas/core/reshape/merge.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pandas/core/nanops.py b/pandas/core/nanops.py index 6356aa0e9cf24..027f458614bd8 100644 --- a/pandas/core/nanops.py +++ b/pandas/core/nanops.py @@ -13,8 +13,8 @@ from pandas.core.dtypes.common import ( _get_dtype, is_any_int_dtype, is_bool_dtype, is_complex, is_complex_dtype, is_datetime64_dtype, is_datetime_or_timedelta_dtype, is_float, - is_float_dtype, is_integer, is_integer_dtype, - is_numeric_dtype, is_object_dtype, is_scalar, is_timedelta64_dtype) + is_float_dtype, is_integer, is_integer_dtype, is_numeric_dtype, + is_object_dtype, is_scalar, is_timedelta64_dtype) from pandas.core.dtypes.missing import isna, na_value_for_dtype, notna import pandas.core.common as com diff --git a/pandas/core/reshape/merge.py b/pandas/core/reshape/merge.py index 5024c18902739..fd0ed5773ac9b 100644 --- a/pandas/core/reshape/merge.py +++ b/pandas/core/reshape/merge.py @@ -18,8 +18,8 @@ ensure_float64, ensure_int64, ensure_object, is_array_like, is_bool, is_bool_dtype, is_categorical_dtype, is_datetime64_dtype, is_datetime64tz_dtype, is_datetimelike, is_dtype_equal, is_float_dtype, - is_int64_dtype, is_integer, is_integer_dtype, - is_list_like, is_number, is_numeric_dtype, needs_i8_conversion) + is_int64_dtype, is_integer, is_integer_dtype, is_list_like, is_number, + is_numeric_dtype, needs_i8_conversion) from pandas.core.dtypes.missing import isnull, na_value_for_dtype from pandas import Categorical, DataFrame, Index, MultiIndex, Series, Timedelta From 2566a18489d003a3c3220263ad640f69dafd3a6d Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Mon, 26 Nov 2018 15:10:56 -0800 Subject: [PATCH 14/18] dummy commit to force CI From 6dda1be9c6d69e7abb7f1f300bd6fc34b2f97620 Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Mon, 26 Nov 2018 17:36:19 -0800 Subject: [PATCH 15/18] separated conditions --- pandas/core/reshape/merge.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/pandas/core/reshape/merge.py b/pandas/core/reshape/merge.py index fd0ed5773ac9b..16d0fc657e621 100644 --- a/pandas/core/reshape/merge.py +++ b/pandas/core/reshape/merge.py @@ -1604,10 +1604,14 @@ def _factorize_keys(lk, rk, sort=True): lk = ensure_int64(lk.codes) rk = ensure_int64(rk) - elif (issubclass(lk.dtype.type, (np.integer, np.timedelta64, - np.datetime64)) and - issubclass(rk.dtype.type, (np.integer, np.timedelta64, - np.datetime64))): + elif is_integer_dtype(lk) and is_integer_dtype(rk): + # GH#23917 TODO: needs tests for case where lk is integer-dtype + # and rk is datetime-dtype + klass = libhashtable.Int64Factorizer + lk = ensure_int64(com.values_from_object(lk)) + rk = ensure_int64(com.values_from_object(rk)) + elif needs_i8_conversion(lk) and needs_i8_conversion(rk): + # GH#23917 TODO: Needs tests for period_dtype, non-matching dtypes klass = libhashtable.Int64Factorizer lk = ensure_int64(com.values_from_object(lk)) rk = ensure_int64(com.values_from_object(rk)) From 3d8752f18705faec4184e53177574fc99e2da582 Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Mon, 26 Nov 2018 17:59:27 -0800 Subject: [PATCH 16/18] docstring fixup --- pandas/core/arrays/datetimes.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/pandas/core/arrays/datetimes.py b/pandas/core/arrays/datetimes.py index 41c28c5ee3b93..4d3caaacca1c1 100644 --- a/pandas/core/arrays/datetimes.py +++ b/pandas/core/arrays/datetimes.py @@ -1458,15 +1458,18 @@ def maybe_convert_dtype(data, copy): """ Convert data based on dtype conventions, issuing deprecation warnings or errors where appropriate. - Parameters + + Parameters ---------- data : np.ndarray or pd.Index copy : bool - Returns + + Returns ------- data : np.ndarray or pd.Index copy : bool - Raises + + Raises ------ TypeError : PeriodDType data is passed """ From 71483b51a8715202dcea112eff36dd0a748d629e Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Mon, 26 Nov 2018 19:15:07 -0800 Subject: [PATCH 17/18] revert usage of needs_i8_conversion --- pandas/core/reshape/merge.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pandas/core/reshape/merge.py b/pandas/core/reshape/merge.py index 16d0fc657e621..dfbee5656da7d 100644 --- a/pandas/core/reshape/merge.py +++ b/pandas/core/reshape/merge.py @@ -1610,8 +1610,9 @@ def _factorize_keys(lk, rk, sort=True): klass = libhashtable.Int64Factorizer lk = ensure_int64(com.values_from_object(lk)) rk = ensure_int64(com.values_from_object(rk)) - elif needs_i8_conversion(lk) and needs_i8_conversion(rk): - # GH#23917 TODO: Needs tests for period_dtype, non-matching dtypes + elif (issubclass(lk.dtype.type, (np.timedelta64, np.datetime64)) and + issubclass(rk.dtype.type, (np.timedelta64, np.datetime64))): + # GH#23917 TODO: Needs tests for non-matching dtypes klass = libhashtable.Int64Factorizer lk = ensure_int64(com.values_from_object(lk)) rk = ensure_int64(com.values_from_object(rk)) From e0593bb0ad2469eccbf3b7706765a77ac5cd5d36 Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Mon, 26 Nov 2018 20:01:09 -0800 Subject: [PATCH 18/18] dummy commit to force CI