Skip to content

REGR: Fix comparison broadcasting over array of Intervals #35938

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 9 commits into from
Aug 31, 2020
1 change: 1 addition & 0 deletions doc/source/whatsnew/v1.1.2.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Fixed regressions
- Regression in :meth:`DatetimeIndex.intersection` incorrectly raising ``AssertionError`` when intersecting against a list (:issue:`35876`)
- Fix regression in updating a column inplace (e.g. using ``df['col'].fillna(.., inplace=True)``) (:issue:`35731`)
- Performance regression for :meth:`RangeIndex.format` (:issue:`35712`)
- Regression in :meth:`DataFrame.replace` where a ``TypeError`` would be raised when attempting to replace elements of type :class:`Interval` (:issue:`35931`)
-


Expand Down
5 changes: 5 additions & 0 deletions pandas/_libs/interval.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,11 @@ cdef class Interval(IntervalMixin):
self_tuple = (self.left, self.right, self.closed)
other_tuple = (other.left, other.right, other.closed)
return PyObject_RichCompare(self_tuple, other_tuple, op)
elif util.is_array(other):
return np.array(
[PyObject_RichCompare(self, x, op) for x in other],
dtype=bool,
)

return NotImplemented

Expand Down
7 changes: 7 additions & 0 deletions pandas/tests/frame/methods/test_replace.py
Original file line number Diff line number Diff line change
Expand Up @@ -1581,3 +1581,10 @@ def test_replace_with_compiled_regex(self):
result = df.replace({regex: "z"}, regex=True)
expected = pd.DataFrame(["z", "b", "c"])
tm.assert_frame_equal(result, expected)

def test_replace_intervals(self):
# https://github.com/pandas-dev/pandas/issues/35931
df = pd.DataFrame({"a": [pd.Interval(0, 1), pd.Interval(0, 1)]})
result = df.replace({"a": {pd.Interval(0, 1): "x"}})
expected = pd.DataFrame({"a": ["x", "x"]})
tm.assert_frame_equal(result, expected)
12 changes: 12 additions & 0 deletions pandas/tests/scalar/interval/test_arithmetic.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,15 @@ def test_numeric_interval_add_timedelta_raises(interval, delta):

with pytest.raises((TypeError, ValueError), match=msg):
delta + interval


@pytest.mark.parametrize("klass", [timedelta, np.timedelta64, Timedelta])
def test_timdelta_add_timestamp_interval(klass):
delta = klass(0)
expected = Interval(Timestamp("2020-01-01"), Timestamp("2020-02-01"))

result = delta + expected
assert result == expected

result = expected + delta
assert result == expected
9 changes: 9 additions & 0 deletions pandas/tests/scalar/interval/test_interval.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import pytest

from pandas import Interval, Period, Timedelta, Timestamp
import pandas._testing as tm
import pandas.core.common as com


Expand Down Expand Up @@ -267,3 +268,11 @@ def test_constructor_errors_tz(self, tz_left, tz_right):
msg = "left and right must have the same time zone"
with pytest.raises(error, match=msg):
Interval(left, right)

def test_equality_comparison_broadcasts_over_array(self):
# https://github.com/pandas-dev/pandas/issues/35931
interval = Interval(0, 1)
arr = np.array([interval, interval])
result = interval == arr
expected = np.array([True, True])
tm.assert_numpy_array_equal(result, expected)