From 0736468858a8255107433d9113cfa3e1226b24bd Mon Sep 17 00:00:00 2001 From: Khor Chean Wei Date: Sat, 19 Feb 2022 19:01:11 +0800 Subject: [PATCH 01/13] Update base.py --- pandas/core/indexes/base.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index c346f88e75ebe..725e354a66e45 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -1077,7 +1077,11 @@ def astype(self, dtype, copy: bool = True): with rewrite_exception(type(values).__name__, type(self).__name__): new_values = values.astype(dtype, copy=copy) - elif is_float_dtype(self.dtype) and needs_i8_conversion(dtype): + elif ( + is_float_dtype(self.dtype) + and needs_i8_conversion(dtype) + and np.isnan(values) == False + ): # NB: this must come before the ExtensionDtype check below # TODO: this differs from Series behavior; can/should we align them? raise TypeError( From 9b9fa3907858363f36f863f4b345407fa5ee36e7 Mon Sep 17 00:00:00 2001 From: Khor Chean Wei Date: Sat, 19 Feb 2022 19:01:36 +0800 Subject: [PATCH 02/13] Update test_constructors.py --- pandas/tests/series/test_constructors.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pandas/tests/series/test_constructors.py b/pandas/tests/series/test_constructors.py index 3b7ae28be68fa..9ffb5f1c3fde2 100644 --- a/pandas/tests/series/test_constructors.py +++ b/pandas/tests/series/test_constructors.py @@ -1995,3 +1995,11 @@ def test_numpy_array(input_dict, expected): def test_numpy_array_np_v1p19(): with pytest.raises(KeyError, match="0"): np.array([Series({1: 1})]) + + +def test_series_with_NAs_and_interval_of_datetime_dtype(): + # GH#41805 + result = pd.Series(data=[None], dtype="interval[datetime64[ns]]") + expected = pd.Series(np.nan, dtype="interval[datetime64[ns]]") + + tm.assert_series_equal(result, expected) From 8fe34a8a8e17d507c3a2262dfa698931bfb74603 Mon Sep 17 00:00:00 2001 From: "chean.wei.khor" Date: Sat, 19 Feb 2022 19:05:07 +0800 Subject: [PATCH 03/13] pep 8 issues --- pandas/core/indexes/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 725e354a66e45..7b695a7b89fe7 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -1080,7 +1080,7 @@ def astype(self, dtype, copy: bool = True): elif ( is_float_dtype(self.dtype) and needs_i8_conversion(dtype) - and np.isnan(values) == False + and not np.isnan(values) ): # NB: this must come before the ExtensionDtype check below # TODO: this differs from Series behavior; can/should we align them? From 8744e0da672f681204f76174ccfefc9234746cd1 Mon Sep 17 00:00:00 2001 From: "chean.wei.khor" Date: Sat, 19 Feb 2022 20:37:51 +0800 Subject: [PATCH 04/13] add pre commit --- pandas/tests/series/test_constructors.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/tests/series/test_constructors.py b/pandas/tests/series/test_constructors.py index 9ffb5f1c3fde2..57cb8be236068 100644 --- a/pandas/tests/series/test_constructors.py +++ b/pandas/tests/series/test_constructors.py @@ -1999,7 +1999,7 @@ def test_numpy_array_np_v1p19(): def test_series_with_NAs_and_interval_of_datetime_dtype(): # GH#41805 - result = pd.Series(data=[None], dtype="interval[datetime64[ns]]") - expected = pd.Series(np.nan, dtype="interval[datetime64[ns]]") + result = Series(data=[None], dtype="interval[datetime64[ns]]") + expected = Series(np.nan, dtype="interval[datetime64[ns]]") tm.assert_series_equal(result, expected) From 7facc5ca350bbc21ec20908a44b51989768a4a75 Mon Sep 17 00:00:00 2001 From: "chean.wei.khor" Date: Sun, 20 Feb 2022 12:57:40 +0800 Subject: [PATCH 05/13] add any to np.isnan(values) --- pandas/core/indexes/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 7b695a7b89fe7..99eb6c239bac6 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -1080,7 +1080,7 @@ def astype(self, dtype, copy: bool = True): elif ( is_float_dtype(self.dtype) and needs_i8_conversion(dtype) - and not np.isnan(values) + and not np.isnan(values).any() ): # NB: this must come before the ExtensionDtype check below # TODO: this differs from Series behavior; can/should we align them? From c74e208b26862a0d0e5c15d86e1603ffec1f5a69 Mon Sep 17 00:00:00 2001 From: "chean.wei.khor" Date: Thu, 24 Feb 2022 22:45:11 +0800 Subject: [PATCH 06/13] add --- pandas/core/indexes/base.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 97fc443dc0089..64fa90310bb41 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -1076,11 +1076,10 @@ def astype(self, dtype, copy: bool = True): if isinstance(values, ExtensionArray): with rewrite_exception(type(values).__name__, type(self).__name__): new_values = values.astype(dtype, copy=copy) - elif ( is_float_dtype(self.dtype) and needs_i8_conversion(dtype) - and not np.isnan(values).any() + and dtype != np.dtype("M8[ns]") ): # NB: this must come before the ExtensionDtype check below # TODO: this differs from Series behavior; can/should we align them? From 75d7e546a96f69d1d4d96e287f0fcaad44244af1 Mon Sep 17 00:00:00 2001 From: "chean.wei.khor" Date: Sat, 26 Feb 2022 21:17:31 +0800 Subject: [PATCH 07/13] datetime and nan --- pandas/core/indexes/base.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 64fa90310bb41..3445e615df635 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -1076,11 +1076,9 @@ def astype(self, dtype, copy: bool = True): if isinstance(values, ExtensionArray): with rewrite_exception(type(values).__name__, type(self).__name__): new_values = values.astype(dtype, copy=copy) - elif ( - is_float_dtype(self.dtype) - and needs_i8_conversion(dtype) - and dtype != np.dtype("M8[ns]") - ): + elif dtype == np.dtype("M8[ns]") and np.isnan(values).any(): + new_values = values.astype(dtype, copy=copy) + elif is_float_dtype(self.dtype) and needs_i8_conversion(dtype): # NB: this must come before the ExtensionDtype check below # TODO: this differs from Series behavior; can/should we align them? raise TypeError( From 5331f2380bac8845cd758a300b994cc07d83963d Mon Sep 17 00:00:00 2001 From: "chean.wei.khor" Date: Sun, 6 Mar 2022 22:49:19 +0800 Subject: [PATCH 08/13] add --- pandas/core/construction.py | 7 +++++++ pandas/core/indexes/base.py | 2 -- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/pandas/core/construction.py b/pandas/core/construction.py index 17cdf6665aa99..e22dd9a29b343 100644 --- a/pandas/core/construction.py +++ b/pandas/core/construction.py @@ -773,6 +773,13 @@ def _try_cast( # special case. return maybe_cast_to_datetime(arr, dtype) # TODO: copy? + from pandas import IntervalDtype + + if ( + isinstance(dtype, IntervalDtype) + and np.isnan(np.array(arr).astype("float")).any() + ): + return np.array(arr) array_type = dtype.construct_array_type()._from_sequence subarr = array_type(arr, dtype=dtype, copy=copy) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index d50c71fcb004f..a0d33efb87cea 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -1076,8 +1076,6 @@ def astype(self, dtype, copy: bool = True): if isinstance(values, ExtensionArray): with rewrite_exception(type(values).__name__, type(self).__name__): new_values = values.astype(dtype, copy=copy) - elif dtype == np.dtype("M8[ns]") and np.isnan(values).any(): - new_values = values.astype(dtype, copy=copy) elif is_float_dtype(self.dtype) and needs_i8_conversion(dtype): # NB: this must come before the ExtensionDtype check below # TODO: this differs from Series behavior; can/should we align them? From c55a74238dd3e299096c6e6992b85e9d610660d2 Mon Sep 17 00:00:00 2001 From: "chean.wei.khor" Date: Tue, 8 Mar 2022 20:17:16 +0800 Subject: [PATCH 09/13] nan --- pandas/core/construction.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/pandas/core/construction.py b/pandas/core/construction.py index e22dd9a29b343..94c21ed152d9e 100644 --- a/pandas/core/construction.py +++ b/pandas/core/construction.py @@ -775,11 +775,8 @@ def _try_cast( # TODO: copy? from pandas import IntervalDtype - if ( - isinstance(dtype, IntervalDtype) - and np.isnan(np.array(arr).astype("float")).any() - ): - return np.array(arr) + if isinstance(dtype, IntervalDtype) and isna(arr).any(): + return np.array(arr).astype(IntervalDtype) array_type = dtype.construct_array_type()._from_sequence subarr = array_type(arr, dtype=dtype, copy=copy) From 39b28392ae715891a4efe7444c54479866eca04b Mon Sep 17 00:00:00 2001 From: "chean.wei.khor" Date: Tue, 8 Mar 2022 22:23:22 +0800 Subject: [PATCH 10/13] add --- pandas/core/indexes/base.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 5efceff55901b..d717e5cfb1083 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -1076,6 +1076,7 @@ def astype(self, dtype, copy: bool = True): if isinstance(values, ExtensionArray): with rewrite_exception(type(values).__name__, type(self).__name__): new_values = values.astype(dtype, copy=copy) + elif is_float_dtype(self.dtype) and needs_i8_conversion(dtype): # NB: this must come before the ExtensionDtype check below # TODO: this differs from Series behavior; can/should we align them? From aa9db9d3257885f5ee70fa84b32ed1e388ab9195 Mon Sep 17 00:00:00 2001 From: "chean.wei.khor" Date: Wed, 9 Mar 2022 00:10:30 +0800 Subject: [PATCH 11/13] test --- pandas/core/construction.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/core/construction.py b/pandas/core/construction.py index 94c21ed152d9e..d24cd0be4194c 100644 --- a/pandas/core/construction.py +++ b/pandas/core/construction.py @@ -775,8 +775,8 @@ def _try_cast( # TODO: copy? from pandas import IntervalDtype - if isinstance(dtype, IntervalDtype) and isna(arr).any(): - return np.array(arr).astype(IntervalDtype) + if isinstance(dtype, IntervalDtype) and isna(arr).all(): + return np.asarray(arr).astype(IntervalDtype, copy=False) array_type = dtype.construct_array_type()._from_sequence subarr = array_type(arr, dtype=dtype, copy=copy) From d5a9f45a1f62888cac9080141fd4882d35a07e25 Mon Sep 17 00:00:00 2001 From: "chean.wei.khor" Date: Wed, 9 Mar 2022 10:16:48 +0800 Subject: [PATCH 12/13] import in extended form --- pandas/core/construction.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/construction.py b/pandas/core/construction.py index d24cd0be4194c..38be8848ad4fd 100644 --- a/pandas/core/construction.py +++ b/pandas/core/construction.py @@ -27,6 +27,7 @@ from pandas.errors import IntCastingNaNError from pandas.util._exceptions import find_stack_level +from pandas.core.dtypes import IntervalDtype from pandas.core.dtypes.base import ( ExtensionDtype, _registry as registry, @@ -773,7 +774,6 @@ def _try_cast( # special case. return maybe_cast_to_datetime(arr, dtype) # TODO: copy? - from pandas import IntervalDtype if isinstance(dtype, IntervalDtype) and isna(arr).all(): return np.asarray(arr).astype(IntervalDtype, copy=False) From 7a8efa8028e37f5d5f29a7ceb37e0fa659644cee Mon Sep 17 00:00:00 2001 From: "chean.wei.khor" Date: Wed, 9 Mar 2022 20:18:42 +0800 Subject: [PATCH 13/13] add astype --- pandas/core/construction.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/construction.py b/pandas/core/construction.py index 38be8848ad4fd..a3f71cc18454e 100644 --- a/pandas/core/construction.py +++ b/pandas/core/construction.py @@ -27,7 +27,6 @@ from pandas.errors import IntCastingNaNError from pandas.util._exceptions import find_stack_level -from pandas.core.dtypes import IntervalDtype from pandas.core.dtypes.base import ( ExtensionDtype, _registry as registry, @@ -53,6 +52,7 @@ ) from pandas.core.dtypes.dtypes import ( DatetimeTZDtype, + IntervalDtype, PandasDtype, ) from pandas.core.dtypes.generic import (