Skip to content

Commit

Permalink
BUG: DatetimeIndex.union returning object dtype for indexes with the …
Browse files Browse the repository at this point in the history
…same tz but different units (#55259)

* add DatetimeTZDtype._get_common_type

* mypy
  • Loading branch information
lukemanley authored Sep 25, 2023
1 parent ce814c2 commit 2e3cb76
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 1 deletion.
2 changes: 1 addition & 1 deletion doc/source/whatsnew/v2.2.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ Categorical

Datetimelike
^^^^^^^^^^^^
-
- Bug in :meth:`DatetimeIndex.union` returning object dtype for tz-aware indexes with the same timezone but different units (:issue:`55238`)
-

Timedelta
Expand Down
7 changes: 7 additions & 0 deletions pandas/core/dtypes/dtypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -928,6 +928,13 @@ def __setstate__(self, state) -> None:
self._tz = state["tz"]
self._unit = state["unit"]

def _get_common_dtype(self, dtypes: list[DtypeObj]) -> DtypeObj | None:
if all(isinstance(t, DatetimeTZDtype) and t.tz == self.tz for t in dtypes):
np_dtype = np.max([cast(DatetimeTZDtype, t).base for t in [self, *dtypes]])
unit = np.datetime_data(np_dtype)[0]
return type(self)(unit=unit, tz=self.tz)
return super()._get_common_dtype(dtypes)

@cache_readonly
def index_class(self) -> type_t[DatetimeIndex]:
from pandas import DatetimeIndex
Expand Down
8 changes: 8 additions & 0 deletions pandas/tests/indexes/datetimes/test_setops.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,14 @@ def test_union_with_DatetimeIndex(self, sort):
# Fails with "AttributeError: can't set attribute"
i2.union(i1, sort=sort)

def test_union_same_timezone_different_units(self):
# GH 55238
idx1 = date_range("2000-01-01", periods=3, tz="UTC").as_unit("ms")
idx2 = date_range("2000-01-01", periods=3, tz="UTC").as_unit("us")
result = idx1.union(idx2)
expected = date_range("2000-01-01", periods=3, tz="UTC").as_unit("us")
tm.assert_index_equal(result, expected)

# TODO: moved from test_datetimelike; de-duplicate with version below
def test_intersection2(self):
first = tm.makeDateIndex(10)
Expand Down

0 comments on commit 2e3cb76

Please sign in to comment.