Skip to content

Commit 13cbfbe

Browse files
jbrockmendelmeeseeksmachine
authored andcommitted
Backport PR pandas-dev#36440: REGR: Series[numeric] comparison with str raising on numexpr path
1 parent 711f923 commit 13cbfbe

File tree

5 files changed

+31
-17
lines changed

5 files changed

+31
-17
lines changed

doc/source/whatsnew/v1.1.3.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ Fixed regressions
3434
- Fixed regression in :meth:`Series.__getitem__` incorrectly raising when the input was a tuple (:issue:`35534`)
3535
- Fixed regression in :meth:`Series.__getitem__` incorrectly raising when the input was a frozenset (:issue:`35747`)
3636
- Fixed regression in :meth:`read_excel` with ``engine="odf"`` caused ``UnboundLocalError`` in some cases where cells had nested child nodes (:issue:`36122`,:issue:`35802`)
37-
-
37+
- Fixed regression in :class:`DataFrame` and :class:`Series` comparisons between numeric arrays and strings (:issue:`35700`,:issue:`36377`)
3838

3939
.. ---------------------------------------------------------------------------
4040

pandas/core/indexes/base.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -135,10 +135,14 @@ def cmp_method(self, other):
135135
with np.errstate(all="ignore"):
136136
result = ops.comp_method_OBJECT_ARRAY(op, self._values, other)
137137

138-
else:
138+
elif is_interval_dtype(self.dtype):
139139
with np.errstate(all="ignore"):
140140
result = op(self._values, np.asarray(other))
141141

142+
else:
143+
with np.errstate(all="ignore"):
144+
result = ops.comparison_op(self._values, np.asarray(other), op)
145+
142146
if is_bool_dtype(result):
143147
return result
144148
return ops.invalid_comparison(self, other, op)

pandas/core/ops/array_ops.py

+5
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
is_bool_dtype,
2424
is_integer_dtype,
2525
is_list_like,
26+
is_numeric_v_string_like,
2627
is_object_dtype,
2728
is_scalar,
2829
)
@@ -235,6 +236,10 @@ def comparison_op(left: ArrayLike, right: Any, op) -> ArrayLike:
235236
else:
236237
res_values = np.zeros(lvalues.shape, dtype=bool)
237238

239+
elif is_numeric_v_string_like(lvalues, rvalues):
240+
# GH#36377 going through the numexpr path would incorrectly raise
241+
return invalid_comparison(lvalues, rvalues, op)
242+
238243
elif is_object_dtype(lvalues.dtype):
239244
res_values = comp_method_OBJECT_ARRAY(op, lvalues, rvalues)
240245

pandas/tests/arithmetic/test_numeric.py

+20
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,26 @@ def test_compare_invalid(self):
8989
b.name = pd.Timestamp("2000-01-01")
9090
tm.assert_series_equal(a / b, 1 / (b / a))
9191

92+
def test_numeric_cmp_string_numexpr_path(self, box):
93+
# GH#36377, GH#35700
94+
xbox = box if box is not pd.Index else np.ndarray
95+
96+
obj = pd.Series(np.random.randn(10 ** 5))
97+
obj = tm.box_expected(obj, box, transpose=False)
98+
99+
result = obj == "a"
100+
101+
expected = pd.Series(np.zeros(10 ** 5, dtype=bool))
102+
expected = tm.box_expected(expected, xbox, transpose=False)
103+
tm.assert_equal(result, expected)
104+
105+
result = obj != "a"
106+
tm.assert_equal(result, ~expected)
107+
108+
msg = "Invalid comparison between dtype=float64 and str"
109+
with pytest.raises(TypeError, match=msg):
110+
obj < "a"
111+
92112

93113
# ------------------------------------------------------------------
94114
# Numeric dtypes Arithmetic with Datetime/Timedelta Scalar

pandas/tests/indexes/test_numpy_compat.py

-15
Original file line numberDiff line numberDiff line change
@@ -114,18 +114,3 @@ def test_numpy_ufuncs_other(index, func):
114114
else:
115115
with pytest.raises(Exception):
116116
func(index)
117-
118-
119-
def test_elementwise_comparison_warning():
120-
# https://github.com/pandas-dev/pandas/issues/22698#issuecomment-458968300
121-
# np.array([1, 2]) == 'a' returns False, and produces a
122-
# FutureWarning that it'll be [False, False] in the future.
123-
# We just want to ensure that comes through.
124-
# When NumPy dev actually enforces this change, we'll need to skip
125-
# this test.
126-
idx = Index([1, 2])
127-
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
128-
result = idx == "a"
129-
130-
expected = np.array([False, False])
131-
tm.assert_numpy_array_equal(result, expected)

0 commit comments

Comments
 (0)