From 8923cc854c1b4a0f0cd14ed039efee18b2379257 Mon Sep 17 00:00:00 2001 From: Brock Date: Mon, 18 Jan 2021 21:03:26 -0800 Subject: [PATCH 1/3] BUG: setting dt64 values into Series[int] incorrectly casting dt64->int --- pandas/core/internals/blocks.py | 12 +++++++++++ pandas/tests/series/indexing/test_setitem.py | 21 ++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index 1356b9d3b2ca3..4b645e548a58b 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -991,6 +991,18 @@ def setitem(self, indexer, value): # set else: + if ( + self.is_object + and not is_ea_value + and arr_value.dtype.kind in ["m", "M"] + ): + # https://github.com/numpy/numpy/issues/12550 + # numpy will incorrect cast to int if we're not careful + if is_list_like(value): + value = list(value) + else: + value = [value] * len(values[indexer]) + values[indexer] = value if transpose: diff --git a/pandas/tests/series/indexing/test_setitem.py b/pandas/tests/series/indexing/test_setitem.py index 7f469f361fec7..c0a60d6d6a0d4 100644 --- a/pandas/tests/series/indexing/test_setitem.py +++ b/pandas/tests/series/indexing/test_setitem.py @@ -239,6 +239,27 @@ def test_setitem_callable_other(self): tm.assert_series_equal(ser, expected) +class TestSetitemCasting: + @pytest.mark.parametrize("dtype", ["M8[ns]", "m8[ns]"]) + def test_setitem_dt64_into_int_series(self, dtype): + # dont cast dt64 to int when doing this setitem + orig = Series([1, 2, 3]) + + val = np.datetime64("2021-01-18 13:25:00", "ns") + if dtype == "m8[ns]": + val = val - val + + ser = orig.copy() + ser[:-1] = val + expected = Series([val, val, 3], dtype=object) + tm.assert_series_equal(ser, expected) + assert isinstance(ser[0], type(val)) + + ser = orig.copy() + ser[:-1] = np.array([val, val]) + tm.assert_series_equal(ser, expected) + + @pytest.mark.parametrize( "obj,expected,key", [ From 1076052f7f62e0415ca3dbdda705d5f6c5aa2c3d Mon Sep 17 00:00:00 2001 From: Brock Date: Tue, 19 Jan 2021 12:18:00 -0800 Subject: [PATCH 2/3] Whatsnew --- doc/source/whatsnew/v1.3.0.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/source/whatsnew/v1.3.0.rst b/doc/source/whatsnew/v1.3.0.rst index 6a85bfd852e19..24f31832be8ec 100644 --- a/doc/source/whatsnew/v1.3.0.rst +++ b/doc/source/whatsnew/v1.3.0.rst @@ -281,6 +281,7 @@ Indexing - Bug in :meth:`DataFrame.loc` dropping levels of :class:`MultiIndex` when :class:`DataFrame` used as input has only one row (:issue:`10521`) - Bug in setting ``timedelta64`` values into numeric :class:`Series` failing to cast to object dtype (:issue:`39086`) - Bug in setting :class:`Interval` values into a :class:`Series` or :class:`DataFrame` with mismatched :class:`IntervalDtype` incorrectly casting the new values to the existing dtype (:issue:`39120`) +- Bug in setting ``datetime64`` values into a :class:`Series` with integer-dtype incorrect casting the datetime64 values to integers (:issue:`39266`) Missing ^^^^^^^ From 38b5646dda9fe820e33e0570b6473a763eb14217 Mon Sep 17 00:00:00 2001 From: Brock Date: Wed, 20 Jan 2021 14:28:15 -0800 Subject: [PATCH 3/3] de-nest condition --- pandas/core/internals/blocks.py | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index 884161849e68c..758ee24543d1d 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -987,19 +987,17 @@ def setitem(self, indexer, value): # TODO(EA2D): special case not needed with 2D EA values[indexer] = value.to_numpy(values.dtype).reshape(-1, 1) - # set + elif self.is_object and not is_ea_value and arr_value.dtype.kind in ["m", "M"]: + # https://github.com/numpy/numpy/issues/12550 + # numpy will incorrect cast to int if we're not careful + if is_list_like(value): + value = list(value) + else: + value = [value] * len(values[indexer]) + + values[indexer] = value + else: - if ( - self.is_object - and not is_ea_value - and arr_value.dtype.kind in ["m", "M"] - ): - # https://github.com/numpy/numpy/issues/12550 - # numpy will incorrect cast to int if we're not careful - if is_list_like(value): - value = list(value) - else: - value = [value] * len(values[indexer]) values[indexer] = value