Skip to content

Commit b66160d

Browse files
authored
BUG: setting dt64 values into Series[int] incorrectly casting dt64->int (pandas-dev#39266)
1 parent 45be21e commit b66160d

File tree

3 files changed

+33
-1
lines changed

3 files changed

+33
-1
lines changed

doc/source/whatsnew/v1.3.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,7 @@ Indexing
335335
- Bug in :meth:`DataFrame.__getitem__` and :meth:`Series.__getitem__` always raising ``KeyError`` when slicing with existing strings an :class:`Index` with milliseconds (:issue:`33589`)
336336
- Bug in setting ``timedelta64`` values into numeric :class:`Series` failing to cast to object dtype (:issue:`39086`)
337337
- 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`)
338+
- Bug in setting ``datetime64`` values into a :class:`Series` with integer-dtype incorrect casting the datetime64 values to integers (:issue:`39266`)
338339
- Bug in incorrectly raising in :meth:`Index.insert`, when setting a new column that cannot be held in the existing ``frame.columns``, or in :meth:`Series.reset_index` or :meth:`DataFrame.reset_index` instead of casting to a compatible dtype (:issue:`39068`)
339340
- Bug in :meth:`RangeIndex.append` where a single object of length 1 was concatenated incorrectly (:issue:`39401`)
340341

pandas/core/internals/blocks.py

+11-1
Original file line numberDiff line numberDiff line change
@@ -968,8 +968,18 @@ def setitem(self, indexer, value):
968968
# TODO(EA2D): special case not needed with 2D EA
969969
values[indexer] = value.to_numpy(values.dtype).reshape(-1, 1)
970970

971-
# set
971+
elif self.is_object and not is_ea_value and arr_value.dtype.kind in ["m", "M"]:
972+
# https://github.com/numpy/numpy/issues/12550
973+
# numpy will incorrect cast to int if we're not careful
974+
if is_list_like(value):
975+
value = list(value)
976+
else:
977+
value = [value] * len(values[indexer])
978+
979+
values[indexer] = value
980+
972981
else:
982+
973983
values[indexer] = value
974984

975985
if transpose:

pandas/tests/series/indexing/test_setitem.py

+21
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,27 @@ def test_setitem_callable_other(self):
257257
tm.assert_series_equal(ser, expected)
258258

259259

260+
class TestSetitemCasting:
261+
@pytest.mark.parametrize("dtype", ["M8[ns]", "m8[ns]"])
262+
def test_setitem_dt64_into_int_series(self, dtype):
263+
# dont cast dt64 to int when doing this setitem
264+
orig = Series([1, 2, 3])
265+
266+
val = np.datetime64("2021-01-18 13:25:00", "ns")
267+
if dtype == "m8[ns]":
268+
val = val - val
269+
270+
ser = orig.copy()
271+
ser[:-1] = val
272+
expected = Series([val, val, 3], dtype=object)
273+
tm.assert_series_equal(ser, expected)
274+
assert isinstance(ser[0], type(val))
275+
276+
ser = orig.copy()
277+
ser[:-1] = np.array([val, val])
278+
tm.assert_series_equal(ser, expected)
279+
280+
260281
@pytest.mark.parametrize(
261282
"obj,expected,key",
262283
[

0 commit comments

Comments
 (0)