Skip to content

Commit 3126408

Browse files
committed
Rephrase whatsnew entry, move tests
1 parent 44d22a7 commit 3126408

File tree

3 files changed

+70
-33
lines changed

3 files changed

+70
-33
lines changed

doc/source/whatsnew/v1.0.0.rst

+4
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,10 @@ Categorical
288288
- :meth:`Categorical.searchsorted` and :meth:`CategoricalIndex.searchsorted` now work on unordered categoricals also (:issue:`21667`)
289289
- Added test to assert roundtripping to parquet with :func:`DataFrame.to_parquet` or :func:`read_parquet` will preserve Categorical dtypes for string types (:issue:`27955`)
290290
- Changed the error message in :meth:`Categorical.remove_categories` to always show the invalid removals as a set (:issue:`28669`)
291+
- Using date accessors on a categorical dtyped series of datetimes was not returning a Series (or DataFrame) of the
292+
same type as if one used the .str. / .dt. on a Series of that type, e.g. when accessing :meth:`Series.dt.tz_localize` on a
293+
:class:`Categorical` with duplicate entries, the accessor was skipping duplicates (:issue: `27952`)
294+
-
291295

292296

293297
Datetimelike

pandas/tests/indexes/test_category.py

-33
Original file line numberDiff line numberDiff line change
@@ -1125,36 +1125,3 @@ def test_engine_type(self, dtype, engine_type):
11251125
ci.values._codes = ci.values._codes.astype("int64")
11261126
assert np.issubdtype(ci.codes.dtype, dtype)
11271127
assert isinstance(ci._engine, engine_type)
1128-
1129-
def test_dt_tz_localize(self, tz_aware_fixture):
1130-
# GH 27952
1131-
tz = tz_aware_fixture
1132-
datetimes = pd.Series(
1133-
["2019-01-01", "2019-01-01", "2019-01-02"], dtype="datetime64[ns]"
1134-
)
1135-
categorical = datetimes.astype("category")
1136-
result = categorical.dt.tz_localize(tz)
1137-
expected = datetimes.dt.tz_localize(tz)
1138-
tm.assert_series_equal(result, expected)
1139-
1140-
def test_dt_tz_convert(self, tz_aware_fixture):
1141-
# GH 27952
1142-
tz = tz_aware_fixture
1143-
datetimes = pd.Series(
1144-
["2019-01-01", "2019-01-01", "2019-01-02"], dtype="datetime64[ns, MET]"
1145-
)
1146-
categorical = datetimes.astype("category")
1147-
result = categorical.dt.tz_convert(tz)
1148-
expected = datetimes.dt.tz_convert(tz)
1149-
tm.assert_series_equal(result, expected)
1150-
1151-
@pytest.mark.parametrize("accessor", ["year", "month", "day"])
1152-
def test_dt_other_accessors(self, accessor):
1153-
# GH 27952
1154-
datetimes = pd.Series(
1155-
["2018-01-01", "2018-01-01", "2019-01-02"], dtype="datetime64[ns]"
1156-
)
1157-
categorical = datetimes.astype("category")
1158-
result = getattr(categorical.dt, accessor)
1159-
expected = getattr(datetimes.dt, accessor)
1160-
tm.assert_series_equal(result, expected)

pandas/tests/series/test_datetime_values.py

+66
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,72 @@ def test_dt_namespace_accessor_categorical(self):
344344
expected = Series([2017, 2017, 2018, 2018], name="foo")
345345
tm.assert_series_equal(result, expected)
346346

347+
def test_dt_tz_localize(self, tz_aware_fixture):
348+
# GH 27952
349+
tz = tz_aware_fixture
350+
datetimes = pd.Series(
351+
["2019-01-01", "2019-01-01", "2019-01-02"], dtype="datetime64[ns]"
352+
)
353+
categorical = datetimes.astype("category")
354+
result = categorical.dt.tz_localize(tz)
355+
expected = datetimes.dt.tz_localize(tz)
356+
tm.assert_series_equal(result, expected)
357+
358+
def test_dt_tz_convert(self, tz_aware_fixture):
359+
# GH 27952
360+
tz = tz_aware_fixture
361+
datetimes = pd.Series(
362+
["2019-01-01", "2019-01-01", "2019-01-02"], dtype="datetime64[ns, MET]"
363+
)
364+
categorical = datetimes.astype("category")
365+
result = categorical.dt.tz_convert(tz)
366+
expected = datetimes.dt.tz_convert(tz)
367+
tm.assert_series_equal(result, expected)
368+
369+
@pytest.mark.parametrize("accessor", ["year", "month", "day"])
370+
def test_dt_other_accessors(self, accessor):
371+
# GH 27952
372+
datetimes = pd.Series(
373+
["2018-01-01", "2018-01-01", "2019-01-02"], dtype="datetime64[ns]"
374+
)
375+
categorical = datetimes.astype("category")
376+
result = getattr(categorical.dt, accessor)
377+
expected = getattr(datetimes.dt, accessor)
378+
tm.assert_series_equal(result, expected)
379+
380+
def test_dt_tz_localize(self, tz_aware_fixture):
381+
# GH 27952
382+
tz = tz_aware_fixture
383+
datetimes = pd.Series(
384+
["2019-01-01", "2019-01-01", "2019-01-02"], dtype="datetime64[ns]"
385+
)
386+
categorical = datetimes.astype("category")
387+
result = categorical.dt.tz_localize(tz)
388+
expected = datetimes.dt.tz_localize(tz)
389+
tm.assert_series_equal(result, expected)
390+
391+
def test_dt_tz_convert(self, tz_aware_fixture):
392+
# GH 27952
393+
tz = tz_aware_fixture
394+
datetimes = pd.Series(
395+
["2019-01-01", "2019-01-01", "2019-01-02"], dtype="datetime64[ns, MET]"
396+
)
397+
categorical = datetimes.astype("category")
398+
result = categorical.dt.tz_convert(tz)
399+
expected = datetimes.dt.tz_convert(tz)
400+
tm.assert_series_equal(result, expected)
401+
402+
@pytest.mark.parametrize("accessor", ["year", "month", "day"])
403+
def test_dt_other_accessors(self, accessor):
404+
# GH 27952
405+
datetimes = pd.Series(
406+
["2018-01-01", "2018-01-01", "2019-01-02"], dtype="datetime64[ns]"
407+
)
408+
categorical = datetimes.astype("category")
409+
result = getattr(categorical.dt, accessor)
410+
expected = getattr(datetimes.dt, accessor)
411+
tm.assert_series_equal(result, expected)
412+
347413
def test_dt_accessor_no_new_attributes(self):
348414
# https://github.com/pandas-dev/pandas/issues/10673
349415
s = Series(date_range("20130101", periods=5, freq="D"))

0 commit comments

Comments
 (0)