Skip to content

Commit 14b4c07

Browse files
authored
BUG: Series[object].__setitem__(ndarray[M8ns]_with_matching_size) (#43868)
1 parent 5b00a47 commit 14b4c07

File tree

4 files changed

+20
-32
lines changed

4 files changed

+20
-32
lines changed

doc/source/whatsnew/v1.4.0.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,7 @@ Indexing
446446
- Bug in :meth:`DataFrame.query` where method calls in query strings led to errors when the ``numexpr`` package was installed. (:issue:`22435`)
447447
- Bug in :meth:`DataFrame.nlargest` and :meth:`Series.nlargest` where sorted result did not count indexes containing ``np.nan`` (:issue:`28984`)
448448
- Bug in indexing on a non-unique object-dtype :class:`Index` with an NA scalar (e.g. ``np.nan``) (:issue:`43711`)
449+
- Bug in :meth:`Series.__setitem__` with object dtype when setting an array with matching size and dtype='datetime64[ns]' or dtype='timedelta64[ns]' incorrectly converting the datetime/timedeltas to integers (:issue:`43868`)
449450
-
450451

451452
Missing

pandas/core/indexers/utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ def check_setitem_lengths(indexer, value, values) -> bool:
174174
if not (
175175
isinstance(indexer, np.ndarray)
176176
and indexer.dtype == np.bool_
177-
and len(indexer[indexer]) == len(value)
177+
and indexer.sum() == len(value)
178178
):
179179
raise ValueError(
180180
"cannot set using a list-like indexer "

pandas/core/internals/blocks.py

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@
4646
from pandas.core.dtypes.common import (
4747
is_1d_only_ea_dtype,
4848
is_1d_only_ea_obj,
49-
is_categorical_dtype,
5049
is_dtype_equal,
5150
is_extension_array_dtype,
5251
is_list_like,
@@ -91,8 +90,6 @@
9190
Categorical,
9291
DatetimeArray,
9392
ExtensionArray,
94-
FloatingArray,
95-
IntegerArray,
9693
IntervalArray,
9794
PandasArray,
9895
PeriodArray,
@@ -110,7 +107,6 @@
110107
from pandas.core.indexers import (
111108
check_setitem_lengths,
112109
is_empty_indexer,
113-
is_exact_shape_match,
114110
is_scalar_indexer,
115111
)
116112
import pandas.core.missing as missing
@@ -928,18 +924,15 @@ def setitem(self, indexer, value):
928924
if is_extension_array_dtype(getattr(value, "dtype", None)):
929925
# We need to be careful not to allow through strings that
930926
# can be parsed to EADtypes
931-
is_ea_value = True
932927
arr_value = value
933928
else:
934-
is_ea_value = False
935929
arr_value = np.asarray(value)
936930

937931
if transpose:
938932
values = values.T
939933

940934
# length checking
941935
check_setitem_lengths(indexer, value, values)
942-
exact_match = is_exact_shape_match(values, arr_value)
943936

944937
if is_empty_indexer(indexer, arr_value):
945938
# GH#8669 empty indexers
@@ -950,30 +943,6 @@ def setitem(self, indexer, value):
950943
# be e.g. a list; see GH#6043
951944
values[indexer] = value
952945

953-
elif exact_match and is_categorical_dtype(arr_value.dtype):
954-
# GH25495 - If the current dtype is not categorical,
955-
# we need to create a new categorical block
956-
values[indexer] = value
957-
958-
elif exact_match and is_ea_value:
959-
# GH#32395 if we're going to replace the values entirely, just
960-
# substitute in the new array
961-
if not self.is_object and isinstance(value, (IntegerArray, FloatingArray)):
962-
# _can_hold_element will only allow us to get here if value
963-
# has no NA entries.
964-
values[indexer] = value.to_numpy(value.dtype.numpy_dtype)
965-
else:
966-
values[indexer] = np.asarray(value)
967-
968-
# if we are an exact match (ex-broadcasting),
969-
# then use the resultant dtype
970-
elif exact_match:
971-
# We are setting _all_ of the array's values, so can cast to new dtype
972-
values[indexer] = value
973-
974-
elif is_ea_value:
975-
values[indexer] = value
976-
977946
else:
978947
# error: Argument 1 to "setitem_datetimelike_compat" has incompatible type
979948
# "Union[ndarray, ExtensionArray]"; expected "ndarray"

pandas/tests/series/indexing/test_setitem.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,24 @@ def test_setitem_with_tz_dst(self, indexer_sli):
141141
indexer_sli(ser)[[1, 2]] = vals
142142
tm.assert_series_equal(ser, exp)
143143

144+
def test_object_series_setitem_dt64array_exact_match(self):
145+
# make sure the dt64 isn't cast by numpy to integers
146+
# https://github.com/numpy/numpy/issues/12550
147+
148+
ser = Series({"X": np.nan}, dtype=object)
149+
150+
indexer = [True]
151+
152+
# "exact_match" -> size of array being set matches size of ser
153+
value = np.array([4], dtype="M8[ns]")
154+
155+
ser.iloc[indexer] = value
156+
157+
expected = Series([value[0]], index=["X"], dtype=object)
158+
assert all(isinstance(x, np.datetime64) for x in expected.values)
159+
160+
tm.assert_series_equal(ser, expected)
161+
144162

145163
class TestSetitemScalarIndexer:
146164
def test_setitem_negative_out_of_bounds(self):

0 commit comments

Comments
 (0)