Skip to content
1 change: 1 addition & 0 deletions doc/source/whatsnew/v0.25.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1053,6 +1053,7 @@ Indexing
- Bug in :meth:`DataFrame.loc` and :meth:`DataFrame.iloc` on a :class:`DataFrame` with a single timezone-aware datetime64[ns] column incorrectly returning a scalar instead of a :class:`Series` (:issue:`27110`)
- Bug in :class:`CategoricalIndex` and :class:`Categorical` incorrectly raising ``ValueError`` instead of ``TypeError`` when a list is passed using the ``in`` operator (``__contains__``) (:issue:`21729`)
- Bug in setting a new value in a :class:`Series` with a :class:`Timedelta` object incorrectly casting the value to an integer (:issue:`22717`)
- Bug in :class:`Series` setting a new key (``__setitem__``) with a timezone-aware datetime incorrectly raising ``ValueError`` (:issue:`12862`)
-
Missing
Expand Down
7 changes: 7 additions & 0 deletions pandas/core/series.py
Original file line number Diff line number Diff line change
Expand Up @@ -1268,6 +1268,13 @@ def _set_with(self, key, value):
except Exception:
pass

if is_scalar(key) and not is_integer(key) and key not in self.index:
# GH#12862 adding an new key to the Series
# Note: have to exclude integers because that is ambiguously
# position-based
self.loc[key] = value
return

if is_scalar(key):
key = [key]
elif not isinstance(key, (list, Series, np.ndarray)):
Expand Down
22 changes: 21 additions & 1 deletion pandas/tests/indexing/test_loc.py
Original file line number Diff line number Diff line change
Expand Up @@ -802,7 +802,7 @@ def test_loc_setitem_with_scalar_index(self, indexer, value):

assert is_scalar(result) and result == "Z"

def test_loc_coerceion(self):
def test_loc_coercion(self):

# 12411
df = DataFrame({"date": [Timestamp("20130101").tz_localize("UTC"), pd.NaT]})
Expand Down Expand Up @@ -838,6 +838,26 @@ def test_loc_coerceion(self):
result = df.iloc[3:]
tm.assert_series_equal(result.dtypes, expected)

def test_setitem_new_key_tz(self):
# GH#12862 should not raise on assigning the second value
vals = [
pd.to_datetime(42).tz_localize("UTC"),
pd.to_datetime(666).tz_localize("UTC"),
]
expected = pd.Series(vals, index=["foo", "bar"])

ser = pd.Series()
ser["foo"] = vals[0]
ser["bar"] = vals[1]

tm.assert_series_equal(ser, expected)

ser = pd.Series()
ser.loc["foo"] = vals[0]
ser.loc["bar"] = vals[1]

tm.assert_series_equal(ser, expected)

def test_loc_non_unique(self):
# GH3659
# non-unique indexer with loc slice
Expand Down
2 changes: 1 addition & 1 deletion pandas/tests/series/indexing/test_indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,7 @@ def test_setitem_with_tz_dst():
tm.assert_series_equal(s, exp)


def test_categorial_assigning_ops():
def test_categorical_assigning_ops():
orig = Series(Categorical(["b", "b"], categories=["a", "b"]))
s = orig.copy()
s[:] = "a"
Expand Down