Skip to content

REGR: preserve freq in DTI/TDI outer join #32166

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Feb 26, 2020
1 change: 1 addition & 0 deletions doc/source/whatsnew/v1.1.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ Other API changes
will now be ``min`` and ``max`` to match with numeric dtypes in :meth:`DataFrame.describe` (:issue:`30164`)
- :meth:`Groupby.groups` now returns an abbreviated representation when called on large dataframes (:issue:`1135`)
- ``loc`` lookups with an object-dtype :class:`Index` and an integer key will now raise ``KeyError`` instead of ``TypeError`` when key is missing (:issue:`31905`)
- Joining on :class:`DatetimeIndex` or :class:`TimedeltaIndex` will preserve ``freq`` in simple cases (:issue:`32166`)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i guess need to backport, can you move to 1.02

-

Backwards incompatible API changes
Expand Down
17 changes: 7 additions & 10 deletions pandas/core/indexes/datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -919,17 +919,14 @@ def _is_convertible_to_index_for_join(cls, other: Index) -> bool:
return True
return False

def _wrap_joined_index(self, joined, other):
def _wrap_joined_index(self, joined: np.ndarray, other):
assert other.dtype == self.dtype, (other.dtype, self.dtype)
name = get_op_result_name(self, other)
if self._can_fast_union(other):
joined = self._shallow_copy(joined)
joined.name = name
return joined
else:
kwargs = {}
if hasattr(self, "tz"):
kwargs["tz"] = getattr(other, "tz", None)
return type(self)._simple_new(joined, name, **kwargs)

freq = self.freq if self._can_fast_union(other) else None
new_data = type(self._data)._simple_new(joined, dtype=self.dtype, freq=freq)

return type(self)._simple_new(new_data, name=name)

# --------------------------------------------------------------------
# List-Like Methods
Expand Down
13 changes: 13 additions & 0 deletions pandas/tests/indexes/datetimes/test_join.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,16 @@ def test_naive_aware_conflicts(self):

with pytest.raises(TypeError, match=msg):
aware.join(naive)

@pytest.mark.parametrize("tz", [None, "US/Pacific"])
def test_join_preserves_freq(self, tz):
# GH#32157
dti = date_range("2016-01-01", periods=10, tz=tz)
result = dti[:5].join(dti[5:], how="outer")
assert result.freq == dti.freq
tm.assert_index_equal(result, dti)

result = dti[:5].join(dti[6:], how="outer")
assert result.freq is None
expected = dti.delete(5)
tm.assert_index_equal(result, expected)
12 changes: 12 additions & 0 deletions pandas/tests/indexes/timedeltas/test_join.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,15 @@ def test_does_not_convert_mixed_integer(self):
assert cols.dtype == np.dtype("O")
assert cols.dtype == joined.dtype
tm.assert_index_equal(cols, joined)

def test_join_preserves_freq(self):
# GH#32157
tdi = timedelta_range("1 day", periods=10)
result = tdi[:5].join(tdi[5:], how="outer")
assert result.freq == tdi.freq
tm.assert_index_equal(result, tdi)

result = tdi[:5].join(tdi[6:], how="outer")
assert result.freq is None
expected = tdi.delete(5)
tm.assert_index_equal(result, expected)